# 기능정의서: 작업지시 관리 (P02)

## 1. 개요

| 항목 | 내용 |
|------|------|
| **화면ID** | P02-01 |
| **화면명** | 작업지시 목록 |
| **메뉴경로** | 생산관리 > 작업지시 관리 |
| **화면유형** | 목록 + 대시보드 |
| **접근권한** | 생산관리자, 공정관리자, 관리자 |

### 1.1 화면 목적
- 수주에서 생성된 작업지시서를 공정별로 관리
- 작업 상태 모니터링 및 진행률 추적
- 담당자 배정 및 승인 프로세스 관리
- 자재 투입 현황 확인

### 1.2 연관 화면
| 연관화면 | 관계 | 설명 |
|----------|------|------|
| 수주 상세 (S05-03) | 선행 | 수주에서 생산지시 → 작업지시 자동 생성 |
| 작업지시 상세 (P02-03) | 후행 | 목록 클릭 시 상세 화면 이동 |
| 작업지시 수정 (P02-04) | 후행 | 수정 버튼 클릭 시 이동 |
| 작업실적 (P03) | 연동 | 작업 완료 시 실적 데이터 생성 |

---

## 2. 화면 레이아웃

```
┌─────────────────────────────────────────────────────────────────────────┐
│ [PageHeader] 작업지시 목록                    [목록뷰/공정관리뷰] [미배정 N건 배정] │
├─────────────────────────────────────────────────────────────────────────┤
│ [알림배너] 담당자 미배정 작업지시가 있습니다 (빨간색)        [담당자 배정하기] │
├─────────────────────────────────────────────────────────────────────────┤
│ [알림배너] 승인 대기중인 작업지시가 있습니다 (주황색)        [승인하러 가기]   │
├─────────────────────────────────────────────────────────────────────────┤
│ [알림배너] 실시간 변동 알림 (파란색)                                    [X]│
│   - WO-2024-0042: 우선순위 변경 (보통 → 긴급)               방금 전      │
│   - WO-2024-0038: 납기일 변경                               5분 전      │
├─────────────────────────────────────────────────────────────────────────┤
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐                     │
│ │ 전체     │ │ 작업대기  │ │ 작업중   │ │ 작업완료  │  [대시보드 카드]     │
│ │ 125건    │ │ 45건     │ │ 32건     │ │ 48건     │                     │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘                     │
├─────────────────────────────────────────────────────────────────────────┤
│ [검색창] 작업지시번호, 발주처, 현장명 검색...     [공정 전체 ▼]           │
├─────────────────────────────────────────────────────────────────────────┤
│ [탭필터] 전체(125) | 미배정(8) | 승인대기(5) | 작업대기(45) | 작업중(32) | 작업완료(48) │
├─────────────────────────────────────────────────────────────────────────┤
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ [Table]                                                             │ │
│ │ □ | 작업지시번호 | 현장명    | 공정   | 수량 | 납기   | 담당자 | 상태  │ │
│ │ ──────────────────────────────────────────────────────────────────── │ │
│ │ □ | WO-2024-001 | OO현장   | 스크린 | 5    | 03-15 | 김스크린| 작업중│ │
│ │ □ | WO-2024-002 | XX현장   | 절곡   | 3    | 03-16 | 이절곡  | 대기  │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘
```

---

## 3. 화면 구성요소

### 3.1 헤더 영역

| 구성요소 | 타입 | 설명 |
|----------|------|------|
| 아이콘 | ClipboardList | 작업지시 아이콘 |
| 타이틀 | Text | "작업지시 목록" |
| 뷰모드 토글 | ButtonGroup | 목록뷰 / 공정관리뷰 전환 |
| 미배정 배정 버튼 | Button (Primary) | 미배정 건이 있을 때만 표시 |

### 3.2 알림 배너 영역

#### 3.2.1 담당자 미배정 알림 (빨간색)
| 항목 | 내용 |
|------|------|
| 표시조건 | 미배정 작업지시 > 0 |
| 아이콘 | Users |
| 메시지 | "담당자 미배정 작업지시가 있습니다" |
| 부가설명 | "{N}건의 작업지시에 담당자를 배정해주세요. (수주 자동 생성됨)" |
| 액션버튼 | "담당자 배정하기" → 미배정 탭으로 이동 |

#### 3.2.2 승인대기 알림 (주황색)
| 항목 | 내용 |
|------|------|
| 표시조건 | 승인대기 작업지시 > 0 |
| 아이콘 | Bell |
| 메시지 | "승인 대기중인 작업지시가 있습니다" |
| 부가설명 | "{N}건의 작업지시가 생산관리 승인을 기다리고 있습니다." |
| 액션버튼 | "승인하러 가기" → 승인대기 탭으로 이동 |

#### 3.2.3 실시간 변동 알림 (파란색)
| 항목 | 내용 |
|------|------|
| 표시조건 | 최근 변동사항 존재 시 |
| 내용 | 작업지시번호, 변경유형, 변경내용, 시간 |
| 닫기버튼 | X → 배너 숨김 |
| 전체확인 | "모두 확인 완료" → 알림 초기화 |

### 3.3 대시보드 카드

| 카드 | 아이콘 | 색상 | 표시값 |
|------|--------|------|--------|
| 전체 | ClipboardList | Blue | workOrders.length |
| 작업대기 | Clock | Yellow | status === '작업대기' |
| 작업중 | Factory | Purple | status === '작업중' |
| 작업완료 | CheckCircle | Green | status === '작업완료' |

### 3.4 검색 및 필터

| 구성요소 | 타입 | 설명 |
|----------|------|------|
| 검색창 | SearchInput | 작업지시번호, 발주처, 현장명 통합 검색 |
| 공정필터 | Select | 전체, 스크린, 슬랫, 절곡, 재고생산 |

### 3.5 탭 필터

| 탭ID | 라벨 | 필터조건 | 하이라이트 |
|------|------|----------|------------|
| all | 전체 | 모든 작업지시 | - |
| unassigned | 미배정 | !assignee && status === '작업대기' | count > 0 |
| pending-approval | 승인대기 | approvalStatus === '승인대기' | count > 0 |
| waiting | 작업대기 | status === '작업대기' && approvalStatus !== '승인대기' | - |
| working | 작업중 | status === '작업중' | - |
| complete | 작업완료 | status === '작업완료' | - |

---

## 4. 뷰 모드별 화면

### 4.1 목록뷰 (기본)

#### 테이블 컬럼
| 컬럼 | 필드 | 너비 | 정렬 | 설명 |
|------|------|------|------|------|
| 체크박스 | - | 40px | Center | 다중 선택용 |
| 작업지시번호 | workOrderNo | 120px | Left | 클릭 시 상세 이동 |
| 수주번호 | orderNo | 100px | Left | 연관 수주 |
| 현장명 | siteName | 150px | Left | - |
| 발주처 | customerName | 120px | Left | - |
| 공정 | processType | 80px | Center | 색상 뱃지로 표시 |
| 품목 | productName | 120px | Left | - |
| 수량 | orderQty | 60px | Right | - |
| 우선순위 | priority | 80px | Center | 긴급(빨강), 높음(주황), 보통(회색), 낮음(파랑) |
| 납기일 | dueDate | 100px | Center | D-day 표시 |
| 담당자 | assignee | 100px | Left | 팀명/다중 표시 |
| 상태 | status | 80px | Center | 뱃지 표시 |
| 액션 | - | 150px | Center | 상태별 버튼 |

#### 상태별 액션 버튼
| 상태 | 버튼 | 동작 |
|------|------|------|
| 승인대기 | 승인 | 작업지시 승인 처리 |
| 미배정 | 배정 | 담당자 배정 모달 열기 |
| 작업대기 | 시작 | 작업 시작 (상태 → 작업중) |
| 작업중 | 진행 | 공정 진행 모달 열기 |
| 작업중 | 완료 | 작업 완료 처리 |

### 4.2 공정관리뷰

#### 공정별 관리자 카드
| 공정 | 관리자 | 투입단위 | 설명 |
|------|--------|----------|------|
| 절곡 | 김절곡 | kg→장 | 자재LOT 선택 후 수량 지정 |
| 스크린 | 이스크린 | W×H | 수주W × 자재LOT H 조합 |
| 슬랫 | 박슬랫 | 자동산출 | 높이 기반 절단매수 계산 |

#### 카드 내 표시 정보
| 항목 | 색상 | 설명 |
|------|------|------|
| 대기 | Yellow | 작업대기 건수 |
| 진행중 | Blue | 작업중 건수 |
| 미투입 | Red | 자재 미투입 건수 |
| 미배정 | Gray | 담당자 미배정 건수 |

---

## 5. 모달 다이얼로그

### 5.1 담당자 배정 모달

```
┌─────────────────────────────────────────┐
│ 담당자 배정                        [X] │
├─────────────────────────────────────────┤
│ 작업지시: WO-2024-0042                  │
│ 공정: 스크린 | 현장: OO현장             │
├─────────────────────────────────────────┤
│ [팀 선택]                               │
│ ┌─────────────────────────────────────┐ │
│ │ □ 스크린팀 (3명)                    │ │
│ │   ☑ 김스크린  □ 이스크린  □ 박스크린│ │
│ ├─────────────────────────────────────┤ │
│ │ □ 슬랫팀 (3명)                      │ │
│ │   □ 김슬랫  □ 이슬랫  □ 박슬랫      │ │
│ ├─────────────────────────────────────┤ │
│ │ □ 절곡팀 (2명)                      │ │
│ │   □ 김절곡  □ 이절곡                │ │
│ └─────────────────────────────────────┘ │
├─────────────────────────────────────────┤
│ 선택된 담당자: 김스크린                 │
├─────────────────────────────────────────┤
│              [취소]  [배정 완료]        │
└─────────────────────────────────────────┘
```

| 항목 | 설명 |
|------|------|
| 팀 체크박스 | 팀 전체 선택/해제 토글 |
| 개인 체크박스 | 개별 작업자 선택/해제 |
| 선택 표시 | 선택된 담당자 목록 표시 |
| 배정 완료 | onAssign(workOrderId, selectedAssignees) 호출 |

### 5.2 공정 진행 모달

```
┌─────────────────────────────────────────┐
│ 공정 진행 입력                     [X] │
├─────────────────────────────────────────┤
│ 작업지시: WO-2024-0042                  │
│ 공정: 스크린 | 담당: 김스크린           │
├─────────────────────────────────────────┤
│ 현재 단계: [원단절단 ▼]                 │
│ ──────────────────────────────────────── │
│ 공정흐름: 원단절단 → 미싱 → 앤드락 → 검사 → 포장 │
├─────────────────────────────────────────┤
│ 완료수량:  [    5    ] EA               │
│ 불량수량:  [    0    ] EA               │
├─────────────────────────────────────────┤
│ 비고:                                   │
│ ┌─────────────────────────────────────┐ │
│ │                                     │ │
│ └─────────────────────────────────────┘ │
├─────────────────────────────────────────┤
│              [취소]  [저장]             │
└─────────────────────────────────────────┘
```

#### 공정별 단계 정의
| 공정 | 단계 |
|------|------|
| 스크린 | 원단절단 → 미싱 → 앤드락작업 → 중간검사 → 포장 |
| 슬랫 | 코일절단 → 중간검사 → 미미작업 → 포장 |
| 절곡 | 절단 → 절곡 → 중간검사 → 포장 |
| 재고생산 | 절단 → 절곡 → 중간검사 → 입고 |

### 5.3 삭제 확인 모달

| 항목 | 내용 |
|------|------|
| 표시조건 | 선택된 항목 > 0 |
| 메시지 | "{N}개의 작업지시를 삭제하시겠습니까?" |
| 확인버튼 | 삭제 → onDeleteWorkOrders(selectedIds) |
| 취소버튼 | 모달 닫기 |

---

## 6. 데이터 모델

### 6.1 작업지시 (WorkOrder)

| 필드 | 타입 | 필수 | 설명 |
|------|------|------|------|
| id | number | Y | 고유 ID |
| workOrderNo | string | Y | 작업지시번호 (WO-YYYY-NNNN) |
| orderNo | string | Y | 연관 수주번호 |
| orderId | number | Y | 연관 수주 ID |
| customerName | string | Y | 발주처명 |
| siteName | string | Y | 현장명 |
| processType | string | Y | 공정유형 (스크린/슬랫/절곡/재고생산) |
| productName | string | Y | 품목명 |
| productCode | string | N | 품목코드 |
| orderQty | number | Y | 지시수량 |
| completedQty | number | N | 완료수량 (기본: 0) |
| defectQty | number | N | 불량수량 (기본: 0) |
| priority | string | Y | 우선순위 (긴급/높음/보통/낮음) |
| dueDate | string | Y | 납기일 (YYYY-MM-DD) |
| status | string | Y | 상태 (작업대기/작업중/작업완료) |
| approvalStatus | string | N | 승인상태 (승인대기/승인완료) |
| assignee | string | N | 담당자명 (콤마 구분) |
| assignees | array | N | 담당자 배열 |
| currentStep | string | N | 현재 공정단계 |
| materialInputted | boolean | N | 자재투입 여부 |
| startDate | string | N | 작업시작일 |
| endDate | string | N | 작업완료일 |
| note | string | N | 비고 |

### 6.2 상태 흐름

```
수주 생성 → [승인대기] → 승인 → [작업대기] → 시작 → [작업중] → 완료 → [작업완료]
                                    ↓
                              담당자 배정
```

---

## 7. 이벤트 핸들러

### 7.1 Props

| Props | 타입 | 필수 | 설명 |
|-------|------|------|------|
| workOrders | array | Y | 작업지시 목록 |
| onNavigate | function | Y | 화면 이동 |
| onApprove | function | N | 승인 처리 (id) |
| onAssign | function | N | 담당자 배정 (id, assignees[]) |
| onStartWork | function | N | 작업 시작 (id) |
| onCompleteWork | function | N | 작업 완료 (id) |
| onProgressWork | function | N | 공정 진행 (id, progressData) |
| onDeleteWorkOrders | function | N | 삭제 (ids[]) |

### 7.2 내부 State

| State | 타입 | 초기값 | 설명 |
|-------|------|--------|------|
| search | string | '' | 검색어 |
| activeTab | string | 'all' | 현재 탭 |
| processFilter | string | 'all' | 공정 필터 |
| viewMode | string | 'list' | 뷰모드 (list/manager) |
| selectedIds | array | [] | 선택된 ID 목록 |
| showDeleteModal | boolean | false | 삭제 모달 표시 |
| showAssignModal | boolean | false | 배정 모달 표시 |
| showProgressModal | boolean | false | 진행 모달 표시 |
| selectedWorkOrder | object | null | 선택된 작업지시 |
| selectedAssignees | array | [] | 선택된 담당자 |
| progressData | object | {} | 진행 입력 데이터 |

---

## 8. 비즈니스 로직

### 8.1 담당자 표시 로직

```javascript
const formatAssigneeDisplay = (wo) => {
  const assignees = wo.assignees || (wo.assignee ? wo.assignee.split(', ') : []);

  // 미배정
  if (assignees.length === 0) return { text: '미배정', color: 'red' };

  // 개인
  if (assignees.length === 1) return { text: assignees[0], color: 'gray' };

  // 팀 전체 선택 확인
  for (const team of teams) {
    if (team.members.every(m => assignees.includes(m))) {
      if (assignees.length === team.members.length) {
        return { text: team.name, color: 'blue' };
      }
      return { text: `${team.name} 외 ${assignees.length - team.members.length}명`, color: 'blue' };
    }
  }

  // 다중 선택
  if (assignees.length > 2) {
    return { text: `${assignees[0]} 외 ${assignees.length - 1}명`, color: 'green' };
  }
  return { text: assignees.join(', '), color: 'green' };
};
```

### 8.2 필터링 로직

```javascript
const filtered = workOrders
  .filter(statusFilter[activeTab])           // 탭 필터
  .filter(w => processFilter === 'all' || w.processType === processFilter)  // 공정 필터
  .filter(w =>                               // 검색어 필터
    w.workOrderNo.toLowerCase().includes(search.toLowerCase()) ||
    w.customerName.includes(search) ||
    w.siteName.includes(search)
  );
```

### 8.3 우선순위 스타일

| 우선순위 | 배경색 | 텍스트색 |
|----------|--------|----------|
| 긴급 | bg-red-100 | text-red-700 |
| 높음 | bg-orange-100 | text-orange-700 |
| 보통 | bg-gray-100 | text-gray-600 |
| 낮음 | bg-blue-100 | text-blue-700 |

### 8.4 상태 스타일

| 상태 | 배경색 | 텍스트색 |
|------|--------|----------|
| 작업대기 | bg-yellow-100 | text-yellow-700 |
| 작업중 | bg-blue-100 | text-blue-700 |
| 작업완료 | bg-green-100 | text-green-700 |
| 승인대기 | bg-orange-100 | text-orange-700 |

---

## 9. 연동 화면

### 9.1 상세 화면 이동

```javascript
onNavigate('work-order-detail', { id: wo.id });
```

### 9.2 수정 화면 이동

```javascript
onNavigate('work-order-edit', { id: wo.id });
```

### 9.3 수주에서 작업지시 생성 후 이동

```javascript
// OrderDetail에서 생산지시 완료 시
alert(`✅ ${newWorkOrders.length}개의 작업지시서가 공정별로 자동 생성되었습니다.`);
navigate('work-order-list');
```

---

## 10. 변경이력

| 버전 | 날짜 | 작성자 | 변경내용 |
|------|------|--------|----------|
| 1.0 | 2024-12-15 | Claude | 최초 작성 |
