# MES 모듈 통합 흐름 분석 계획 > **작성일**: 2025-01-09 > **목적**: 견적 → 수주 → 작업지시 + 공정관리 모듈 간 연동 상태 점검 및 문제점 분석 > **기준 문서**: `docs/plans/process-management-plan.md`, `docs/plans/order-management-plan.md`, `docs/plans/work-order-plan.md` > **상태**: ✅ 분석 완료 + 개선 방향 **재결정됨** (2025-01-09 추가 분석) --- ## 📍 현재 진행 상태 | 항목 | 내용 | |------|------| | **마지막 완료 작업** | 공정 관리 페이지 확인 + 개념 명확화 | | **다음 작업** | WorkOrder `process_type` → `process_id` FK 변경 구현 | | **진행률** | 7/7 (100%) | | **마지막 업데이트** | 2025-01-09 | ### ✅ 결정된 개선 방향 (재결정) | 결정 사항 | 내용 | |----------|------| | **WorkOrder.process_type** | `process_type` (varchar) → `process_id` (FK) **변경** | | **Process.process_type** | 공정 구분 → `common_codes`에서 관리 | | **개념 정리** | 공정명(WorkOrder) ≠ 공정구분(Process) 명확히 구분 | --- ## 1. 개요 ### 1.1 배경 MES 시스템의 핵심 모듈인 공정관리, 수주관리, 작업지시가 개별적으로 개발 완료되었으나, 모듈 간 통합 흐름이 제대로 설계되었는지 검증이 필요합니다. ### 1.2 분석 목표 ``` ┌─────────────────────────────────────────────────────────────────┐ │ 🎯 분석 목표 │ ├─────────────────────────────────────────────────────────────────┤ │ 1. 모듈 간 데이터 흐름 검증 │ │ 2. API 연동 상태 점검 │ │ 3. 프론트엔드 연동 상태 점검 │ │ 4. 설계 문제점 및 개선 방안 도출 │ └─────────────────────────────────────────────────────────────────┘ ``` --- ## 2. 분석 대상 ### 2.1 모듈 구성 | 모듈 | 역할 | API 상태 | Frontend 상태 | |------|------|:--------:|:------------:| | **견적관리 (Quote)** | 견적서 작성 및 수주 변환 | ✅ 완료 | ✅ 완료 | | **수주관리 (Order)** | 견적→수주 변환, 생산지시 생성 | ✅ 완료 | ✅ 완료 | | **작업지시 (WorkOrder)** | 실제 생산 작업 관리 | ✅ 완료 | ✅ 완료 | | **공정관리 (Process)** | 공정 템플릿 및 품목 분류 규칙 관리 | ✅ 완료 | ✅ 완료 | ### 2.2 기대 데이터 흐름 ``` ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ 견적관리 │ │ 수주관리 │ │ 작업지시 │ │ 공정관리 │ │ (Quote) │ ──→ │ (Order) │ ──→ │ (WorkOrder) │ ? │ (Process) │ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ │ │ │ │ ▼ ▼ ▼ ▼ - 견적서 작성 - 수주 확정 - 작업 상태 관리 - 공정 템플릿 - 품목/단가 구성 - 생산지시 생성 - 담당자 배정 - 품목 분류 규칙 - 고객 승인 - 납기 관리 - 공정별 진행 - 작업 단계 정의 ``` --- ## 3. 분석 결과 ### 3.0 ✅ 견적관리 → 수주관리 연동 (정상 작동) **API 연동 구현**: ``` POST /api/v1/orders/from-quote/{quoteId} → Order 생성 + Quote 상태 변경 (finalized → converted) ``` **연결 관계**: | 항목 | 내용 | |------|------| | FK 연결 | `orders.quote_id` → `quotes.id` | | 상태 연동 | Quote `finalized` 시에만 수주 변환 가능 | | 중복 방지 | 동일 Quote에 대해 중복 변환 불가 | **Quote 상태 흐름**: ``` draft → sent → approved → finalized → converted (임시저장) (발송) (승인) (확정) (수주변환) ``` **API 핵심 로직** (`api/app/Services/OrderService.php`): ```php public function createFromQuote(int $quoteId): Order { $quote = Quote::findOrFail($quoteId); // 변환 가능 상태 검증 (finalized만 가능) if ($quote->status !== Quote::STATUS_FINALIZED) { throw new BadRequestHttpException(__('error.quote.must_be_finalized')); } // 중복 변환 방지 $existingOrder = Order::where('quote_id', $quoteId)->first(); if ($existingOrder) { throw new BadRequestHttpException(__('error.order.already_exists_from_quote')); } // Order 생성 + Quote 품목 자동 복사 $order = Order::create([ 'quote_id' => $quote->id, 'client_id' => $quote->client_id, 'status_code' => Order::STATUS_DRAFT, // ... 견적 정보 복사 ]); // Quote 상태 변경 $quote->status = Quote::STATUS_CONVERTED; $quote->save(); return $order; } ``` **프론트엔드 구현**: ```typescript // react/src/components/orders/actions.ts export async function createOrderFromQuote( quoteId: string | number ): Promise // react/src/components/quotes/QuotationSelectDialog.tsx // 견적 선택 → 수주 변환 UI 컴포넌트 ``` **데이터 변환**: | Quote 필드 | Order 필드 | 변환 방식 | |-----------|-----------|----------| | `id` | `quote_id` (FK) | 참조 | | `client_id` | `client_id` | 복사 | | `project_name` | `project_name` | 복사 | | `quote_items` | `order_items` | 품목 복사 | | `product_category` | - | 참조용 | **평가**: ✅ **정상 구현됨** - FK 관계, 상태 연동, 중복 방지 모두 정상 --- ### 3.1 ✅ 수주관리 → 작업지시 연동 (정상 작동) **API 연동 구현**: ``` POST /api/v1/orders/{id}/production-order → WorkOrder 생성 + Order 상태 변경 (CONFIRMED → IN_PROGRESS) ``` **연결 관계**: | 항목 | 내용 | |------|------| | FK 연결 | `work_orders.sales_order_id` → `orders.id` | | 상태 연동 | Order CONFIRMED 시에만 생산지시 가능 | | 중복 방지 | 동일 Order에 대해 중복 생성 불가 | **프론트엔드 구현**: ```typescript // react/src/components/orders/actions.ts export async function createProductionOrder( orderId: string, data?: CreateProductionOrderData ): Promise // CreateProductionOrderData 타입 interface CreateProductionOrderData { processType?: 'screen' | 'slat' | 'bending'; priority?: 'urgent' | 'high' | 'normal' | 'low'; assigneeId?: number; teamId?: number; scheduledDate?: string; memo?: string; } ``` **평가**: ✅ **정상 구현됨** --- ### 3.2 🔴 공정관리 → 작업지시 연동 (설계 문제 발견 → 해결 방향 결정) #### 3.2.0 ✅ 개념 명확화 (2025-01-09 추가 분석) **공정 관리 페이지 확인** (`/master-data/process-management`): | 공정코드 | 공정명 | 구분 | 담당부서 | 상태 | |---------|-------|------|---------|------| | P-001 | 슬랫 | 생산 | 경영본부 | 사용중 | | P-002 | 스크린 | 생산 | 개발팀 | 사용중 | **핵심 발견**: ``` ┌─────────────────────────────────────────────────────────────────┐ │ 💡 개념 정리 │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ WorkOrder.process_type = "공정명" (스크린, 슬랫, 절곡) │ │ → 공정 관리 테이블(processes)에서 등록된 공정 │ │ → 하드코딩 ❌ → 공정 테이블 FK로 연결해야 함 ✅ │ │ │ │ Process.process_type = "공정 구분" (생산, 검사, 포장, 조립) │ │ → 공정의 분류/카테고리 │ │ → common_codes에서 관리해야 함 ✅ │ │ │ └─────────────────────────────────────────────────────────────────┘ ``` **최종 정리**: | 구분 | 필드명 | 실제 의미 | 현재 상태 | 올바른 상태 | |------|--------|----------|----------|------------| | **WorkOrder** | `process_type` | 공정명 | 하드코딩 (screen/slat/bending) | **공정 테이블 FK** | | **Process** | `process_type` | 공정 구분 | 하드코딩 (생산/검사/포장/조립) | common_codes | --- #### 3.2.1 process_type 불일치 문제 (기존 분석) | 구분 | 공정관리 (Process) | 작업지시 (WorkOrder) | |------|:------------------:|:-------------------:| | **필드명** | `process_type` | `process_type` | | **값 (Frontend)** | '생산', '검사', '포장', '조립' | 'screen', 'slat', 'bending' | | **값 개수** | 4개 (한글) | 3개 (영문) | | **실제 의미** | 공정 **구분** (카테고리) | 공정 **명** (공정 테이블 데이터) | **문제점**: - 동일한 필드명(`process_type`)을 사용하지만 **완전히 다른 의미** - WorkOrder는 **공정 테이블을 참조해야 하는데** 하드코딩되어 있음 - **FK 관계가 없음** - Process 테이블과 WorkOrder 테이블 연결 없음 #### 3.2.2 코드 증거 **공정관리 타입** (`react/src/types/process.ts`): ```typescript export type ProcessType = '생산' | '검사' | '포장' | '조립'; ``` **작업지시 타입** (`react/src/components/production/WorkOrders/types.ts`): ```typescript export type ProcessType = 'screen' | 'slat' | 'bending'; export const PROCESS_TYPE_LABELS: Record = { screen: '스크린', slat: '슬랫', bending: '절곡', }; ``` **API 모델** (`api/app/Models/Production/WorkOrder.php`): ```php const PROCESS_SCREEN = 'screen'; const PROCESS_SLAT = 'slat'; const PROCESS_BENDING = 'bending'; ``` #### 3.2.3 영향도 분석 | 기능 | 현재 상태 | 문제점 | |------|----------|--------| | 공정 선택 | WorkOrder 생성 시 하드코딩된 3개 옵션만 사용 | Process 테이블 활용 안됨 | | 분류 규칙 | Process에만 존재 | WorkOrder에서 품목 자동 분류 불가 | | 작업 단계 | Process와 WorkOrder 각각 별도 정의 | 데이터 중복 | | 메타데이터 | Process에 풍부한 정보 (인원, 설비, 템플릿) | WorkOrder에서 미활용 | --- ### 3.3 🟡 공정관리 → 수주관리 연동 (연결 없음) **현재 상태**: - Process와 Order 간 직접적인 연결 관계 없음 - 이는 **의도된 설계**로 보임 (공정은 생산 단계에서 적용) --- ## 4. 문제점 요약 ### 4.1 핵심 문제: process_type 이중 정의 ``` ┌─────────────────────────────────────────────────────────────────┐ │ 🔴 핵심 문제 │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ 공정관리(Process)와 작업지시(WorkOrder)가 │ │ 동일한 필드명(process_type)을 사용하지만 │ │ 완전히 다른 값 체계와 목적을 가지고 있음 │ │ │ │ ┌─────────────┐ ┌─────────────┐ │ │ │ Process │ ❌ │ WorkOrder │ │ │ │ (생산/검사) │ ─────── │ (screen/slat) │ │ │ └─────────────┘ 연결없음 └─────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────┘ ``` ### 4.2 문제 유형 분류 | # | 문제 | 심각도 | 영향 | |---|------|:------:|------| | 1 | process_type 값 체계 불일치 | 🔴 높음 | 데이터 일관성, 확장성 | | 2 | Process ↔ WorkOrder FK 부재 | 🔴 높음 | 메타데이터 활용 불가 | | 3 | 공정 정보 중복 정의 | 🟡 중간 | 유지보수 복잡성 | | 4 | 새 공정 추가 시 코드 수정 필요 | 🟡 중간 | 확장성 제한 | --- ## 5. 해결 방안 (검토 필요) ### 5.1 Option A: 현행 유지 (의도된 분리) **전제**: 공정관리와 작업지시가 **서로 다른 도메인**임을 인정 ``` 공정관리 (Process) 작업지시 (WorkOrder) ───────────────── ───────────────── 목적: 품목 분류 자동화 목적: 실제 생산 작업 관리 대상: 모든 품목 유형 대상: 특화 제조품 (스크린/슬랫/절곡) 사용자: 품질/물류팀 사용자: 생산팀 ``` **장점**: - 현재 코드 변경 불필요 - 각 도메인의 독립성 유지 **단점**: - `process_type` 필드명 혼란 지속 - 공정 메타데이터 재활용 불가 **권장 조치**: - WorkOrder의 `process_type`을 `manufacturing_type` 또는 `product_line`으로 **리네이밍** - 문서에 두 개념의 차이 명확히 기술 --- ### 5.2 Option B: 통합 연결 (FK 추가) **전제**: 공정관리가 작업지시의 **상위 템플릿** 역할을 해야 함 ``` Process (공정 템플릿) │ │ process_id (FK) ▼ WorkOrder (작업지시) ``` **필요 변경**: 1. `work_orders` 테이블에 `process_id` FK 추가 2. Process 모델에 제조 공정 유형 추가 (screen, slat, bending) 3. WorkOrder 생성 시 Process 선택 UI 추가 4. 공정별 메타데이터 (작업단계, 인원, 설비) 자동 적용 **장점**: - 데이터 일관성 확보 - 공정 메타데이터 재활용 - 새 공정 추가 시 코드 수정 불필요 **단점**: - DB 마이그레이션 필요 - 기존 데이터 마이그레이션 필요 - API 및 프론트엔드 수정 필요 --- ### 5.3 Option C: 하이브리드 (권장) **전제**: 점진적 통합으로 위험 최소화 **Phase 1**: 명명 정리 (즉시) - WorkOrder의 `process_type` → `manufacturing_type` 리네이밍 - 문서 정리 및 팀 공유 **Phase 2**: 연결 준비 (중기) - Process 모델에 `is_manufacturing` 플래그 추가 - 제조 전용 공정 구분 (screen, slat, bending) **Phase 3**: 통합 (장기) - WorkOrder에 `process_id` FK 추가 (optional) - 메타데이터 연동 구현 --- ## 6. 컨펌 결과 (✅ 결정 완료 → 재결정) | # | 항목 | ~~이전 결정~~ | **최종 결정** | 결정일 | |---|------|-------------|--------------|--------| | 1 | **설계 방향** | ~~Option C (하이브리드)~~ | **Option B** (FK 추가) | 2025-01-09 | | 2 | **필드 변경** | ~~리네이밍만~~ | **FK로 변경** | 2025-01-09 | | 3 | **FK 추가 여부** | ~~❌ 불필요~~ | **✅ 필요** - 공정 테이블 FK | 2025-01-09 | | 4 | **도메인 연결** | ~~독립 도메인~~ | **Process → WorkOrder 연결** | 2025-01-09 | ### 6.0 재결정 사유 ``` ┌─────────────────────────────────────────────────────────────────┐ │ 💡 핵심 발견 (공정 관리 페이지 확인) │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ WorkOrder.process_type 값 (screen, slat, bending)이 │ │ 실제로는 공정 관리 페이지에서 등록된 "공정명"임을 확인 │ │ │ │ /master-data/process-management 등록 현황: │ │ - P-001: 슬랫 (slat) │ │ - P-002: 스크린 (screen) │ │ │ │ ∴ 하드코딩된 값이 아닌 공정 테이블 FK로 연결해야 함 │ │ │ └─────────────────────────────────────────────────────────────────┘ ``` ### 6.1 다음 작업 (FK 추가 구현) ``` WorkOrder `process_type` (varchar) → `process_id` (FK) 변경 작업 범위: 1. DB 마이그레이션 - work_orders.process_type (varchar) 제거 - work_orders.process_id (FK) 추가 → processes.id 참조 - 기존 데이터 마이그레이션 (screen→P-002, slat→P-001, bending→신규등록) 2. API 수정 - api/app/Models/Production/WorkOrder.php - PROCESS_* 상수 제거 - process_type 필드 → process_id FK 필드 - process() BelongsTo 관계 추가 - api/app/Services/OrderService.php (생산지시 생성 로직) - api/app/Services/WorkOrderService.php (비즈니스 로직) - 관련 FormRequest, Resource 클래스 3. Frontend 수정 - react/src/components/production/WorkOrders/types.ts - ProcessType enum 제거 - process_id: number 필드 추가 - process 관계 데이터 타입 추가 - 관련 컴포넌트 (actions.ts, components) - 공정 선택 드롭다운 → API에서 공정 목록 조회 ``` --- ## 7. 참고 문서 - **공정관리 계획**: `docs/plans/process-management-plan.md` - **수주관리 계획**: `docs/plans/order-management-plan.md` - **작업지시 계획**: `docs/plans/work-order-plan.md` - **시스템 아키텍처**: `docs/architecture/system-overview.md` - **품질 체크리스트**: `docs/standards/quality-checklist.md` --- ## 8. 분석 파일 참조 ### 8.1 API 레이어 | 파일 | 역할 | |------|------| | `api/app/Http/Controllers/Api/V1/QuoteController.php` | 견적 CRUD | | `api/app/Http/Controllers/Api/V1/OrderController.php` | 수주 CRUD + 생산지시 생성 | | `api/app/Http/Controllers/V1/ProcessController.php` | 공정 CRUD | | `api/app/Http/Controllers/Api/V1/WorkOrderController.php` | 작업지시 CRUD | | `api/app/Services/QuoteService.php` | 견적 비즈니스 로직 | | `api/app/Services/OrderService.php` | 견적→수주 변환, 수주→작업지시 연동 | | `api/app/Services/WorkOrderService.php` | 작업지시 비즈니스 로직 | ### 8.2 모델 레이어 | 파일 | 핵심 필드 | |------|----------| | `api/app/Models/Quote/Quote.php` | `status` (draft/sent/approved/finalized/converted), `product_category` | | `api/app/Models/Order.php` | `status_code`, `quote_id` (FK) | | `api/app/Models/Process.php` | `process_type` (생산/검사/포장/조립) | | `api/app/Models/Production/WorkOrder.php` | `process_type` (screen/slat/bending), `sales_order_id` (FK) | ### 8.3 프론트엔드 레이어 | 파일 | 역할 | |------|------| | `react/src/components/quotes/types.ts` | Quote 타입 정의 | | `react/src/components/quotes/QuotationSelectDialog.tsx` | 견적 선택 UI | | `react/src/types/process.ts` | Process 타입 정의 | | `react/src/components/production/WorkOrders/types.ts` | WorkOrder 타입 정의 | | `react/src/components/orders/actions.ts` | Order API 호출 + 생산지시 생성 + 견적변환 | | `react/src/components/process-management/actions.ts` | Process API 호출 | | `react/src/components/production/WorkOrders/actions.ts` | WorkOrder API 호출 | --- ## 9. 변경 이력 | 날짜 | 항목 | 변경 내용 | 파일 | 승인 | |------|------|----------|------|------| | 2025-01-09 | 문서 생성 | MES 통합 흐름 분석 완료 | - | - | | 2025-01-09 | 견적 분석 추가 | Quote → Order 연동 분석 (섹션 3.0) | - | - | | 2025-01-09 | 결정 반영 | Option C 선택, 리네이밍 진행, FK 미추가 결정 | - | ✅ | | 2025-01-09 | **재결정** | 공정 관리 페이지 확인 후 **Option B (FK 추가)로 변경** | - | ✅ | ### 9.1 재결정 상세 **재결정 배경**: - 공정 관리 페이지(`/master-data/process-management`) 실제 확인 - `screen`, `slat`, `bending` 값이 공정명(Process Name)임을 확인 - P-001: 슬랫, P-002: 스크린 등록 확인 **이전 결정 → 최종 결정**: | 항목 | 이전 | 최종 | |------|------|------| | 설계 방향 | Option C (하이브리드) | **Option B (FK 추가)** | | 필드 처리 | 리네이밍만 | **FK로 변경** | | FK 추가 | 불필요 | **필요** | | 도메인 관계 | 독립 | **연결** | --- *이 문서는 /plan 스킬로 생성되었습니다.*