Files
sam-docs/plans/document-system-work-log.md
권혁성 c9899eed81 docs:문서관리 마스터/작업일지 계획 문서 업데이트 (Phase 5.3 mng 상세보기 완료 반영)
- 결정사항 #13~#16 추가 (bf_ 분기, 개소별 LOT, 취소 상쇄, 자재 투입 방식 변경 요청)
- mng 작업일지 상세보기 작업 항목 α.1~α.7 추가
- mng 데이터 흐름도, 핵심 파일 경로, 변경 이력 갱신

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 10:02:47 +09:00

16 KiB
Raw Blame History

Phase 5.3: 작업일지 폼 구현 계획

작성일: 2026-02-10 마스터 문서: document-system-master.md 상태: 🔄 진행 중 (3/4+α, mng 상세보기 ) 선행 조건: Phase 5.0과 독립 (검사기준서 없음). 병렬 진행 가능


1. 개요

1.1 목적

mng에서 작업일지 양식 템플릿을 정의하고, React 작업자 화면(/production/worker-screen)의 작업일지 모달에서 해당 양식을 기반으로 작업 내역을 기록/조회할 수 있도록 한다.

1.2 하이브리드 방식

  • 양식 정의: mng 템플릿 시스템 (DocumentTemplate) 활용
  • 전용 UI/로직: React에서 작업일지 전용 컴포넌트로 구현 (검사 성적서와 다른 구조)
  • 이유: 작업일지는 검사 항목표가 아닌, 품목 목록 + 작업 통계 + 특이사항 구조

1.3 현재 상태

항목 상태 비고
React WorkLogContent.tsx 정적 문서, DocumentHeader + 기본정보 + 품목테이블 + 작업내역 + 특이사항
mng 양식 템플릿 WorkLogTemplateSeeder 3종 (스크린:62, 슬랫:63, 절곡:64)
WorkLogModal 양식 연동 공정관리 workLogTemplateId 기반 콘텐츠 분기, processType 폴백
ScreenWorkLogContent 자재 LOT materialLots item_name별 동적 그룹핑 (하드코딩 "내화실" 제거)
API 자재 투입 LOT 조회 materialInputLots 엔드포인트 (stock_transactions 기반)
API 작업일지 전용 getWorkLogTemplate, getWorkLog, createWorkLog (3개 라우트)
작업 통계 계산 calculateWorkStats() 함수 존재 (완료/진행중/대기 수량)
mng 문서 상세보기 show.blade.php 작업일지 전용 섹션 (템플릿 컬럼 기반 동적 렌더링)
mng bf_ backfill 분기 resolveAndBackfillBasicFields: 작업일지=label 기반, 검사=field_key 기반
mng 재단 알고리즘 (PHP) React calculateCutSize 동일 구현. 실리카/와이어/화이바 원단별 설정
mng 개소별 투입자재 LOT work_order_material_inputs → stock_lots JOIN, 개소별 lot_no 매핑
mng 취소 트랜잭션 상쇄 work_order_input + work_order_input_cancel 합산 → 순수 투입량

1.4 성공 기준

  1. mng에서 작업일지 양식 정의 가능 (기본필드, 결재라인)
  2. React에서 WorkOrder 선택 시 작업일지 자동생성 또는 수동생성
  3. 품목 목록(WorkOrderItem[])이 자동으로 테이블에 매핑
  4. 작업 통계(지시수량/완료수량/진행률) 자동 계산
  5. 특이사항 입력/저장 가능

2. 데이터 흐름

WorkOrder (작업지시)
├─ work_order_no: "KD-WO-260210-01"
├─ process_id → Process (공정: 스크린/슬랫/절곡)
├─ sales_order_id → Order (수주)
│  ├─ client_name: "발주처명"
│  └─ site_name: "현장명"
└─ items: WorkOrderItem[]
   ├─ [0] item_name="와이어 스크린", quantity=2, status="completed"
   ├─ [1] item_name="메쉬 스크린", quantity=4, status="in_progress"
   └─ [N] ...

작업일지 생성:
   ↓
Document (작업일지 1건 / 작업지시 1건)
├─ template_id → 작업일지 양식
├─ linkable_type = 'WorkOrder'
├─ linkable_id = work_order.id
├─ status: DRAFT → PENDING → APPROVED
└─ document_data (EAV)
   ├─ 기본필드: 발주처, 현장명, 작업일자, LOT NO, 납기일, 작업지시번호
   ├─ 품목데이터: 행(row) = WorkOrderItem별
   │   ├─ r{행}_item_name = "와이어 스크린"
   │   ├─ r{행}_floor_code = "1F-A"
   │   ├─ r{행}_specification = "W7400×H2950"
   │   ├─ r{행}_quantity = "2"
   │   └─ r{행}_status = "completed"
   ├─ 작업통계: order_qty, completed_qty, in_progress_qty, waiting_qty, progress
   └─ 특이사항: remarks

2.1 mng 상세보기 데이터 흐름 (구현 완료)

DocumentController::show($id)
├─ Document + relations 로드
├─ linkable_type === 'work_order' ?
│  ├─ workOrderItems (work_order_items, options JSON decode)
│  ├─ workOrder (work_orders)
│  ├─ salesOrder (orders, via work_order.sales_order_id)
│  ├─ materialInputLots (stock_transactions: work_order_input + cancel 상쇄)
│  │  └─ 순수 투입량 = SUM(qty) where qty < 0 → abs()
│  └─ itemLotMap (work_order_material_inputs → stock_lots JOIN)
│     └─ groupBy(work_order_item_id) → lot_no 문자열
├─ resolveAndBackfillBasicFields($document)
│  ├─ isWorkLog = sections 없음?
│  ├─ 작업일지 → buildWorkLogResolveMap (label 기반: 발주처, 현장명, 수주일 등)
│  └─ 검사 문서 → buildInspectionResolveMap (field_key 기반: product_name 등)
└─ view('documents.show', [...])

show.blade.php (작업일지 전용 섹션)
├─ 템플릿 컬럼 기반 동적 테이블
│  ├─ 헤더: simple 컬럼 = 1행, complex 컬럼 = colspan + sub_labels 2행
│  ├─ 데이터: $getCellValue (label 기반 매핑), $getSubCellValue (sub_label 매핑)
│  └─ PHP $calculateCutSize (재단 알고리즘: FABRIC_CONFIG 원단별)
├─ 작업 통계 (지시수량/완료/진행중/대기/진행률)
├─ 투입 자재 LOT 테이블 (materialInputLots)
└─ 비고 (remarks)

2.2 중간검사 문서와의 차이

항목 중간검사 작업일지
단위 작업지시 (내부 개소별 행) 작업지시 (1:1)
테이블 내용 검사항목 + 측정값 + 판정 품목 목록 + 상태
통계 적합/부적합 비율 완료/진행중/대기 수량
Footer 부적합 내용 + 종합판정 특이사항
결재 작성→검토→승인 (3단계) 작성→확인 (2단계)

3. 작업 항목

# 작업 상태 완료 기준 비고
5.3.1 mng 작업일지 양식 시더 생성 WorkLogTemplateSeeder 3종. 스크린(62)/슬랫(63)/절곡(64). 공정별 결재+기본필드+컬럼 검사 기준서 섹션 없음, 판정 없음
5.3.2 mng 양식 편집 검증 작업일지 양식 edit → 미리보기 정상 동작 확인 (코드 레벨 검증) 빈 sections/judgement 안전 처리
5.3.3 API 작업일지 생성/저장 getWorkLogTemplate, getWorkLog, createWorkLog 구현. 3개 라우트 추가 EAV 저장, 기본필드 자동매핑, 작업통계 자동계산
5.3.4 React WorkLogContent 양식 기반 전환 양식의 기본필드/결재라인을 API에서 받아 렌더링. 품목테이블/통계는 전용 로직 유지 하이브리드

mng 작업일지 상세보기 (추가 작업, 완료)

# 작업 상태 설명
α.1 resolveAndBackfillBasicFields 작업일지/검사 분기 섹션 유무로 판별. 작업일지=label 기반(발주처, 현장명 등), 검사=field_key 기반(product_name 등)
α.2 show() 메서드 데이터 로딩 확장 workOrder, salesOrder, materialInputLots, itemLotMap 변수 추가
α.3 템플릿 컬럼 기반 동적 테이블 렌더링 template.columns 구조대로 헤더/데이터 렌더링. complex 컬럼(제작사이즈, 규격매수) sub_labels 지원
α.4 PHP 재단 알고리즘 (calculateCutSize) React 동일 구현. FABRIC_CONFIG(실리카1220/와이어1100/화이바1100), 나머지높이+규격(매수) 자동계산
α.5 개소별 투입자재 LOT 매핑 work_order_material_inputs → stock_lots JOIN. 입고 LOT NO 컬럼에 개소별 lot_no 표시
α.6 투입자재 취소 트랜잭션 상쇄 stock_transactions에서 work_order_input(OUT,음수) + work_order_input_cancel(IN,양수) 합산
α.7 작업통계/자재LOT/비고 섹션 지시수량/완료/진행중/대기 통계, 투입 자재 LOT 테이블, 비고 표시

4. 작업일지 구조 (React 현재 기준)

4.1 WorkLogContent.tsx 구조

작업일지 문서
├─ DocumentHeader
│  ├─ 로고 (케이디산업)
│  ├─ 제목: "작업일지"
│  └─ 결재라인: 작성 / 확인
│
├─ 기본 정보 테이블
│  ├─ 발주처 / 현장명
│  ├─ 작업일자 / LOT NO
│  └─ 납기일 / 작업지시번호
│
├─ 품목 테이블
│  ├─ No | 품목명 | 층-부호 | 규격 | 수량 | 상태
│  ├─ [1] 와이어 스크린 | 1F-A | W7400×H2950 | 2 | 완료
│  ├─ [2] 메쉬 스크린 | 2F-B | W5200×H3100 | 4 | 작업중
│  └─ [N] ...
│
├─ 작업내역 (공정별)
│  ├─ 지시수량: 50
│  ├─ 완료수량: 30
│  ├─ 진행률: 60%
│  └─ 대기: 10 / 작업중: 10 / 완료: 30
│
└─ 특이사항
   └─ (자유 텍스트 입력)

4.2 작업 통계 계산 (기존 로직)

function calculateWorkStats(items: WorkOrderItem[]): WorkStats {
    return {
        orderQty: items.length,              // 전체 개소 수
        completedQty: items.filter(i => i.status === 'completed').length,
        inProgressQty: items.filter(i => i.status === 'in_progress').length,
        waitingQty: items.filter(i => i.status === 'waiting').length,
        progress: (completedQty / orderQty) * 100
    }
}

5. 양식 시더 구조 (구현 완료 - 3종)

// WorkLogTemplateSeeder - 공정별 3종
// 스크린(ID:62): 결재 3단계(작성/검토/승인), 규격매수 컬럼(기준폭/900/800/600/400/300)
// 슬랫(ID:63):   결재 4단계(작성/승인×3), 방화유리/조인트바/코일 컬럼
// 절곡(ID:64):   결재 4단계(작성/승인×3), 유형명/세부품명/재질/길이규격 컬럼
//
// 공통: 기본필드 9개(신청업체4+신청내용5), 판정 없음, 비고만
[
    'name' => '스크린 작업일지',  // or 슬랫/절곡
    'category' => '생산/작업일지',
    'title' => '작업일지 (스크린)',
    'company_name' => '케이디산업',
    'footer_remark_label' => '비고',
    'footer_judgement_label' => '',         // NOT NULL 컬럼 → 빈문자열
    'footer_judgement_options' => [],       // 작업일지는 종합판정 없음

    'approval_lines' => [
        ['name' => '작성', 'dept' => '생산', 'role' => '담당자', 'sort_order' => 1],
        ['name' => '확인', 'dept' => '생산', 'role' => '관리자', 'sort_order' => 2],
    ],

    'basic_fields' => [
        ['label' => '발주처', 'field_type' => 'text'],
        ['label' => '현장명', 'field_type' => 'text'],
        ['label' => '작업일자', 'field_type' => 'date'],
        ['label' => 'LOT NO', 'field_type' => 'text'],
        ['label' => '납기일', 'field_type' => 'date'],
        ['label' => '작업지시번호', 'field_type' => 'text'],
    ],

    // 섹션 없음 (작업일지는 검사 기준서가 필요 없음)
    'sections' => [],

    // 컬럼: 품목 테이블용 (React에서 직접 렌더링하므로 참조용)
    'columns' => [
        ['label' => 'No', 'column_type' => 'text', 'width' => '40px'],
        ['label' => '품목명', 'column_type' => 'text', 'width' => '150px'],
        ['label' => '층-부호', 'column_type' => 'text', 'width' => '80px'],
        ['label' => '규격', 'column_type' => 'text', 'width' => '150px'],
        ['label' => '수량', 'column_type' => 'text', 'width' => '60px'],
        ['label' => '상태', 'column_type' => 'select', 'width' => '80px'],
    ],
]

6. 하이브리드 구현 전략

mng 템플릿에서 관리하는 것

  • 결재라인 (작성/확인 or 커스텀)
  • 기본필드 (발주처, 현장명, 작업일자 등)
  • 회사명, 문서 제목

React 전용 로직으로 유지하는 것

  • 품목 테이블 (WorkOrderItem[] 기반 동적 생성)
  • 작업 통계 계산 (calculateWorkStats)
  • 상태 배지 (완료/작업중/대기 → 색상 표시)
  • 특이사항 입력 UI

API 요청 흐름

1. 작업일지 생성 요청
   POST /api/v1/work-orders/{id}/create-work-log
   → Document 생성 (template_id, linkable → WorkOrder)
   → 기본필드 자동매핑 (발주처, 현장명, LOT NO 등)

2. 작업일지 데이터 저장
   PUT /api/v1/documents/{id}
   Body: {
     basic_data: { ... },     // 기본필드 (양식 기반)
     table_data: [ ... ],     // 품목 테이블 (전용 로직)
     stats: { ... },          // 작업 통계 (자동 계산)
     remarks: "특이사항"       // 자유 텍스트
   }

3. 작업일지 조회
   GET /api/v1/documents/{id}
   → 양식 JSON + 저장된 데이터 반환

7. 핵심 파일 경로

mng

파일 용도
mng/database/seeders/WorkLogTemplateSeeder.php 3종 생성 (62/63/64)
mng/app/Http/Controllers/DocumentController.php show() 작업일지 데이터 로딩, resolveAndBackfillBasicFields 분기, buildWorkLogResolveMap
mng/resources/views/documents/show.blade.php 작업일지 전용 섹션 (템플릿 컬럼 동적 렌더링, PHP 재단 알고리즘, 통계, 자재LOT, 비고)

react

파일 용도
react/src/components/production/WorkerScreen/WorkLogModal.tsx 작업일지 모달 (공정관리 양식 연동)
react/src/components/production/WorkerScreen/WorkLogContent.tsx 작업일지 범용 (~280행)
react/src/components/production/WorkOrders/documents/ScreenWorkLogContent.tsx 스크린 작업일지 (자재 LOT 동적화)
react/src/components/production/WorkOrders/documents/SlatWorkLogContent.tsx 슬랫 작업일지
react/src/components/production/WorkOrders/documents/BendingWorkLogContent.tsx 절곡 작업일지
react/src/components/production/WorkerScreen/actions.ts API 호출
react/src/components/document-system/viewer/DocumentViewer.tsx 문서 뷰어

api

파일 용도
api/app/Services/WorkOrderService.php getWorkLogTemplate, getWorkLog, createWorkLog
api/app/Http/Controllers/Api/V1/WorkOrderController.php 작업일지 3개 엔드포인트
api/routes/api/v1/production.php work-log-template, work-log 라우트
api/app/Models/Production/WorkOrder.php documents() MorphMany 관계

8. 변경 이력

날짜 내용
2026-02-10 Phase 5.3 계획 문서 신규 생성
2026-02-11 5.3.1 완료: WorkLogTemplateSeeder 3종 생성 (스크린62/슬랫63/절곡64). 범용(61) 삭제. React 공정별 코드 분석 기반 구조 반영. 판정 없음 확정
2026-02-11 WorkLogModal 공정관리 양식 연동: workLogTemplateId/Name prop 추가, resolveProcessTypeFromTemplate()
2026-02-11 ScreenWorkLogContent 자재 LOT 동적화: "내화실 입고 LOT NO" → materialLots item_name별 그룹핑
2026-02-11 결정: 자재 LOT 역할 분리 — 개소별 품목=작업내역 테이블, 공용 자재=자재 투입 시스템 (예외 필드 없음)
2026-02-12 5.3.2 완료: mng 양식 편집/미리보기 코드 레벨 검증 (빈 sections/judgement 안전 처리 확인)
2026-02-12 5.3.3 완료: API 작업일지 3개 엔드포인트 구현 (getWorkLogTemplate, getWorkLog, createWorkLog). 기본필드 자동매핑, 작업통계 자동계산, EAV 저장
2026-02-12 MNG α.1~7 완료: 작업일지 상세보기 전면 구현
2026-02-12 DocumentController: resolveAndBackfillBasicFields 작업일지(label)/검사(field_key) 분기. buildWorkLogResolveMap, buildInspectionResolveMap 추가
2026-02-12 show.blade.php: 템플릿 컬럼 기반 동적 테이블 (complex 컬럼 sub_labels 지원), PHP 재단 알고리즘 (React calculateCutSize 동일)
2026-02-12 show(): workOrder, salesOrder, materialInputLots(취소 상쇄), itemLotMap(개소별 LOT) 변수 추가
2026-02-12 자재 투입 방식 변경 요청 기록 (수량 입력 → LOT 선택 방식, 미착수)

이 문서는 /plan 스킬로 생성되었습니다.