# [IMPL-2025-12-05] 단가관리 페이지 마이그레이션 계획서

## 개요
- **소스**: sam-design 프로젝트 (`PricingManagement*.tsx`, `PricingWrite.tsx`)
- **대상**: sam-react-prod (Next.js App Router)
- **경로**: `/sales/pricing-management`
- **기존 공통 테이블**: `@/components/common/DataTable/DataTable.tsx` 사용

---

## 스크린샷 분석 결과

### 1. 단가 목록 페이지
- 통계 카드 4개 (전체 품목, 단가 등록, 미등록, 확정)
- 검색창 (품목 코드, 품목명, 규격 검색)
- 탭 필터 (전체/제품/부품/부자재/원자재/소모품/절곡물)
- 데이터 테이블 컬럼: 번호, 품목유형, 품목코드, 품목명, 규격, 단위, 매입단가, 가공비, 판매단가, 마진율, 적용일, 상태, 작업

### 2. 단가 등록 페이지 (미등록 → + 버튼)
- 품목 정보 섹션 (읽기전용): 품목코드, 품목명, 품목유형, 단위, 규격
- 단가 정보 입력:
  - 적용일 (필수)
  - 공급업체, 입고일, 작성자
  - 입고가 (필수), 단위, LOSS(%), 가공비
  - 원가 계산 섹션 (입고가 + 가공비 + LOSS = LOSS 적용 원가)
  - 반올림 규칙, 반올림 단위
  - 마진율(%), 판매단가 (필수)
  - 마진 계산 섹션 (LOSS 적용 원가 vs 판매단가 = 마진)
  - 비고

### 3. 단가 수정 페이지 (활성 상태)
- 등록 페이지와 동일 구조
- 상태 배지 표시 (활성/확정/수정차수)
- 추가 버튼: 이력 조회, 최종 확정, 저장
- 다이얼로그: 이력 조회, 수정 이력 생성, 최종 확정

---

## 파일 구조

```
src/
├── app/[locale]/(protected)/sales/pricing-management/
│   ├── page.tsx                    # 단가 목록 페이지
│   ├── create/
│   │   └── page.tsx               # 단가 등록 페이지 (품목 선택 후)
│   └── [id]/
│       └── edit/
│           └── page.tsx           # 단가 수정 페이지
├── components/
│   └── pricing/
│       ├── PricingListClient.tsx   # 목록 클라이언트 컴포넌트
│       ├── PricingFormClient.tsx   # 등록/수정 폼 컴포넌트
│       ├── PricingStatsCards.tsx   # 통계 카드 컴포넌트
│       ├── PricingHistoryDialog.tsx # 이력 조회 다이얼로그
│       ├── PricingRevisionDialog.tsx # 수정 이력 생성 다이얼로그
│       ├── PricingFinalizeDialog.tsx # 최종 확정 다이얼로그
│       └── types.ts                # 타입 정의
└── lib/api/
    └── pricing.ts                  # API 함수
```

---

## 체크리스트

### Phase 1: 기본 설정 및 타입 정의 ✅
- [x] 1.1 `src/components/pricing/types.ts` 타입 정의 파일 생성
  - [x] `PricingData` 인터페이스
  - [x] `PricingRevision` 인터페이스
  - [x] `PricingFormData` 인터페이스
  - [x] `PricingStats` 인터페이스
- [ ] 1.2 `src/lib/api/pricing.ts` API 함수 파일 생성 (API 연동 시 구현 예정)
  - [ ] `fetchPricingList` - 단가 목록 조회
  - [ ] `fetchPricingById` - 단가 상세 조회
  - [ ] `createPricing` - 단가 등록
  - [ ] `updatePricing` - 단가 수정
  - [ ] `finalizePricing` - 단가 최종 확정
  - [ ] `fetchPricingHistory` - 단가 이력 조회

### Phase 2: 단가 목록 페이지 ✅
- [x] 2.1 통계 카드 (공통 StatCards 컴포넌트 활용)
  - [x] 전체 품목 카드 (Package 아이콘, 파랑)
  - [x] 단가 등록 카드 (DollarSign 아이콘, 초록)
  - [x] 미등록 카드 (AlertCircle 아이콘, 주황)
  - [x] 확정 카드 (CheckCircle2 아이콘, 보라)
- [x] 2.2 `src/components/pricing/PricingListClient.tsx` 생성
  - [x] 공통 DataTable 컴포넌트 연동
  - [x] 탭 필터 구성 (전체/제품/부품/부자재/원자재/소모품/절곡물)
  - [x] 검색 기능 (품목코드, 품목명, 규격)
  - [x] 테이블 컬럼 정의
    - [x] 번호 컬럼
    - [x] 품목유형 컬럼 (Badge)
    - [x] 품목코드 컬럼
    - [x] 품목명 컬럼
    - [x] 규격 컬럼
    - [x] 단위 컬럼
    - [x] 매입단가 컬럼 (금액 포맷)
    - [x] 가공비 컬럼 (금액 포맷)
    - [x] 판매단가 컬럼 (금액 포맷, 굵게)
    - [x] 마진율 컬럼 (Badge, 색상 구분)
    - [x] 적용일 컬럼 (날짜 포맷)
    - [x] 상태 컬럼 (미등록/활성/확정 Badge)
    - [x] 작업 컬럼 (등록/수정/이력 버튼)
  - [x] 품목 마스터 동기화 버튼
- [x] 2.3 `src/app/[locale]/(protected)/sales/pricing-management/page.tsx` 생성
  - [x] 서버 컴포넌트 구성
  - [x] PricingListClient 연동

### Phase 3: 단가 등록/수정 폼 컴포넌트 ✅
- [x] 3.1 `src/components/pricing/PricingFormClient.tsx` 생성
  - [x] 품목 정보 섹션 (읽기전용 카드)
    - [x] 품목 코드
    - [x] 품목명
    - [x] 품목 유형 (Badge)
    - [x] 단위
    - [x] 규격
  - [x] 단가 정보 섹션
    - [x] 적용일 입력 (필수, DatePicker)
    - [x] 공급업체 입력
    - [x] 입고일 입력 (DatePicker)
    - [x] 작성자 입력
    - [x] 입고가 입력 (필수, 숫자)
    - [x] 단위 선택 (Select)
    - [x] LOSS(%) 입력 (숫자)
    - [x] 가공비 입력 (숫자)
  - [x] 원가 계산 섹션 (자동 계산 표시)
    - [x] 입고가 표시
    - [x] 가공비 표시
    - [x] 소계 표시
    - [x] LOSS 적용 금액 표시
    - [x] LOSS 적용 원가 표시 (최종)
  - [x] 반올림 설정
    - [x] 반올림 규칙 선택 (반올림/올림/내림)
    - [x] 반올림 단위 선택 (1/10/100/1000/10000원)
  - [x] 마진율/판매단가 입력
    - [x] 마진율(%) 입력 → 판매단가 자동 계산
    - [x] 판매단가 입력 → 마진율 자동 계산 (필수)
  - [x] 마진 계산 섹션 (자동 계산 표시)
    - [x] LOSS 적용 원가 표시
    - [x] 판매단가 표시
    - [x] 마진 금액 및 % 표시
  - [x] 비고 입력 (Textarea)
  - [x] 수정 모드 상태 표시
    - [x] 최종 확정 배지
    - [x] 수정 차수 배지
    - [x] 활성 상태 배지
  - [x] 버튼 영역
    - [x] 취소 버튼
    - [x] 이력 조회 버튼 (수정 모드, 이력 있을 때)
    - [x] 최종 확정 버튼 (수정 모드, 미확정일 때)
    - [x] 저장 버튼

### Phase 4: 다이얼로그 컴포넌트 ✅
- [x] 4.1 `src/components/pricing/PricingHistoryDialog.tsx` 생성
  - [x] 현재 버전 표시 (파란 배경)
  - [x] 이전 버전 목록 (리비전 번호, 날짜, 수정자, 수정 사유)
  - [x] 각 버전별 단가 정보 표시 (매입단가, 가공비, 판매단가, 마진율)
  - [x] 최초 버전 표시 (회색 배경)
- [x] 4.2 `src/components/pricing/PricingRevisionDialog.tsx` 생성
  - [x] 수정 사유 입력 (필수, Textarea)
  - [x] 취소/수정 이력 저장 버튼
- [x] 4.3 `src/components/pricing/PricingFinalizeDialog.tsx` 생성
  - [x] 확정 대상 정보 요약 (품목명, 매입단가, 판매단가, 마진율)
  - [x] 경고 메시지 (확정 후 수정 불가)
  - [x] 취소/최종 확정 버튼

### Phase 5: 페이지 라우트 구성 ✅
- [x] 5.1 `src/app/[locale]/(protected)/sales/pricing-management/create/page.tsx` 생성
  - [x] 품목 정보 쿼리 파라미터로 전달받기
  - [x] PricingFormClient 연동 (신규 모드)
- [x] 5.2 `src/app/[locale]/(protected)/sales/pricing-management/[id]/edit/page.tsx` 생성
  - [x] 기존 단가 데이터 조회
  - [x] PricingFormClient 연동 (수정 모드)

### Phase 6: 네비게이션 연동 ✅
- [x] 6.1 사이드바 메뉴 추가
  - [x] 판매관리 > 단가관리 메뉴 항목 추가
  - [x] 아이콘: DollarSign
  - [x] 경로: `/sales/pricing-management`

### Phase 7: 테스트 및 검증 ⏳
- [ ] 7.1 기능 테스트
  - [ ] 목록 페이지 로딩
  - [ ] 검색 기능
  - [ ] 탭 필터 기능
  - [ ] 페이지네이션
  - [ ] 신규 등록 플로우
  - [ ] 수정 플로우
  - [ ] 이력 조회
  - [ ] 최종 확정
- [ ] 7.2 반응형 테스트
  - [ ] 데스크톱 레이아웃
  - [ ] 모바일 레이아웃
- [ ] 7.3 스타일 검증
  - [ ] sam-design 스크린샷과 비교

---

## 데이터 타입 참조

```typescript
// PricingData 인터페이스 (sam-design 기준)
interface PricingData {
  id: string;
  itemId: string;
  itemCode: string;
  itemName: string;
  itemType: string;
  specification?: string;
  unit: string;
  effectiveDate: string;      // 적용일
  receiveDate?: string;       // 입고일
  author?: string;            // 작성자
  purchasePrice?: number;     // 매입단가 (입고가)
  processingCost?: number;    // 가공비
  loss?: number;              // LOSS(%)
  roundingRule?: 'round' | 'ceil' | 'floor';  // 반올림 규칙
  roundingUnit?: number;      // 반올림 단위
  marginRate?: number;        // 마진율(%)
  salesPrice?: number;        // 판매단가
  supplier?: string;          // 공급업체
  note?: string;              // 비고

  currentRevision: number;    // 현재 리비전
  isFinal: boolean;           // 최종 확정 여부
  revisions?: PricingRevision[];
  finalizedDate?: string;
  finalizedBy?: string;
  status: 'draft' | 'active' | 'inactive' | 'finalized';

  createdAt: string;
  createdBy: string;
  updatedAt?: string;
  updatedBy?: string;
}

interface PricingRevision {
  revisionNumber: number;
  revisionDate: string;
  revisionBy: string;
  revisionReason?: string;
  previousData: PricingData;
}
```

---

## 원가/마진 계산 로직

```typescript
// LOSS 적용 원가 계산
const calculateCostWithLoss = () => {
  const basePrice = (purchasePrice || 0) + (processingCost || 0);
  const lossRate = (loss || 0) / 100;
  return Math.round(basePrice * (1 + lossRate));
};

// 반올림 적용
const applyRounding = (value: number, rule: 'round' | 'ceil' | 'floor', unit: number) => {
  switch (rule) {
    case 'ceil': return Math.ceil(value / unit) * unit;
    case 'floor': return Math.floor(value / unit) * unit;
    default: return Math.round(value / unit) * unit;
  }
};

// 마진율 → 판매단가 계산
const calculateSalesPrice = (marginRate: number) => {
  const costWithLoss = calculateCostWithLoss();
  const price = costWithLoss * (1 + marginRate / 100);
  return Math.round(applyRounding(price, roundingRule, roundingUnit));
};

// 판매단가 → 마진율 계산
const calculateMarginRate = (salesPrice: number) => {
  const costWithLoss = calculateCostWithLoss();
  if (costWithLoss > 0) {
    return ((salesPrice - costWithLoss) / costWithLoss) * 100;
  }
  return 0;
};
```

---

## 참고 사항

1. **공통 DataTable 사용**: `/components/common/DataTable/DataTable.tsx` 활용
2. **탭 필터**: DataTable의 `tabFilter` prop 활용
3. **검색**: DataTable의 `search` prop 활용
4. **페이지네이션**: DataTable 기본 제공
5. **API 프록시**: HttpOnly 쿠키 사용 시 `/api/proxy/` 경로 활용
6. **라우팅**: Next.js App Router 패턴 준수

---

## 진행 상태

- **시작일**: 2025-12-05
- **현재 단계**: Phase 6 완료, API 연동 대기
- **완료율**: 85% (UI/컴포넌트 마이그레이션 완료, API 연동 및 테스트 대기)

---

## 생성된 파일 목록

| 파일 경로 | 설명 |
|-----------|------|
| `src/components/pricing/types.ts` | 타입 정의 |
| `src/components/pricing/PricingListClient.tsx` | 목록 클라이언트 컴포넌트 |
| `src/components/pricing/PricingFormClient.tsx` | 등록/수정 폼 컴포넌트 |
| `src/components/pricing/PricingHistoryDialog.tsx` | 이력 조회 다이얼로그 |
| `src/components/pricing/PricingRevisionDialog.tsx` | 수정 이력 생성 다이얼로그 |
| `src/components/pricing/PricingFinalizeDialog.tsx` | 최종 확정 다이얼로그 |
| `src/components/pricing/index.ts` | Barrel export |
| `src/app/[locale]/(protected)/sales/pricing-management/page.tsx` | 목록 페이지 |
| `src/app/[locale]/(protected)/sales/pricing-management/create/page.tsx` | 등록 페이지 |
| `src/app/[locale]/(protected)/sales/pricing-management/[id]/edit/page.tsx` | 수정 페이지 |

---

## 변경 이력

| 날짜 | 내용 | 작성자 |
|------|------|--------|
| 2025-12-05 | 최초 계획서 작성 | Claude |
| 2025-12-05 | Phase 1-6 완료 (UI/컴포넌트 마이그레이션) | Claude |
