getTemplateDefinitions(); foreach ($templates as $def) { $this->cleanupExisting($def['name']); $template = DocumentTemplate::create([ 'tenant_id' => $this->tenantId, 'name' => $def['name'], 'category' => '생산/작업일지', 'title' => $def['title'], 'company_name' => '케이디산업', 'footer_remark_label' => '비고', 'footer_judgement_label' => '', 'footer_judgement_options' => [], 'is_active' => true, ]); $this->createApprovalLines($template->id, $def['approval_lines']); $this->createBasicFields($template->id); $this->createColumns($template->id, $def['columns']); $this->command->info("✅ {$def['name']} (ID: {$template->id})"); } } private function getTemplateDefinitions(): array { return [ $this->screenTemplate(), $this->slatTemplate(), $this->bendingTemplate(), ]; } // ─── 스크린 작업일지 ─── // React: ScreenWorkLogContent.tsx // 결재: 작성/검토/승인 (3단계) // 작업내역: No, 입고LOT, 제품명, 부호, 가로/세로, 나머지높이, 규격매수(기준폭/900/800/600/400/300) // 특수: 내화실 입고 LOT NO private function screenTemplate(): array { return [ 'name' => '스크린 작업일지', 'title' => '작업일지 (스크린)', 'approval_lines' => [ ['name' => '작성', 'dept' => '판매/전진', 'role' => '담당자', 'sort_order' => 1], ['name' => '검토', 'dept' => '생산', 'role' => '담당자', 'sort_order' => 2], ['name' => '승인', 'dept' => '품질', 'role' => 'QC', 'sort_order' => 3], ], 'columns' => [ ['label' => 'No.', 'column_type' => 'text', 'width' => '28px', 'sort_order' => 1], ['label' => '입고 LOT NO', 'column_type' => 'text', 'width' => '72px', 'sort_order' => 2], ['label' => '제품명', 'column_type' => 'text', 'width' => '80px', 'sort_order' => 3], ['label' => '부호', 'column_type' => 'text', 'width' => '60px', 'sort_order' => 4], [ 'label' => '제작사이즈(mm)', 'column_type' => 'complex', 'group_name' => '제작사이즈(mm)', 'sub_labels' => ['가로', '세로'], 'width' => '104px', 'sort_order' => 5, ], ['label' => '나머지높이', 'column_type' => 'text', 'width' => '44px', 'sort_order' => 6], [ 'label' => '규격(매수)', 'column_type' => 'complex', 'group_name' => '규격(매수)', 'sub_labels' => ['기준폭', '900', '800', '600', '400', '300'], 'width' => '240px', 'sort_order' => 7, ], ], ]; } // ─── 슬랫 작업일지 ─── // React: SlatWorkLogContent.tsx // 결재: 작성/승인/승인/승인 (4단계) // 작업내역: No, 입고LOT, 방화유리수량, 제품명, 가로/세로/매수(세로), 조인트바수량, 코일사용량, 설치홈/부호 // 특수: 생산량 합계[m²], 조인트바 합계 private function slatTemplate(): array { return [ 'name' => '슬랫 작업일지', 'title' => '작업일지 (슬랫)', 'approval_lines' => [ ['name' => '작성', 'dept' => '생산', 'role' => '담당자', 'sort_order' => 1], ['name' => '승인', 'dept' => '', 'role' => '승인자', 'sort_order' => 2], ['name' => '승인', 'dept' => '', 'role' => '승인자', 'sort_order' => 3], ['name' => '승인', 'dept' => '', 'role' => '승인자', 'sort_order' => 4], ], 'columns' => [ ['label' => 'No.', 'column_type' => 'text', 'width' => '28px', 'sort_order' => 1], ['label' => '입고 LOT NO', 'column_type' => 'text', 'width' => '64px', 'sort_order' => 2], ['label' => '방화유리 수량', 'column_type' => 'text', 'width' => '48px', 'sort_order' => 3], ['label' => '제품명', 'column_type' => 'text', 'width' => '80px', 'sort_order' => 4], [ 'label' => '제작사이즈(mm)-미미제외', 'column_type' => 'complex', 'group_name' => '제작사이즈(mm)-미미제외', 'sub_labels' => ['가로', '세로', '매수(세로)'], 'width' => '140px', 'sort_order' => 5, ], ['label' => '조인트바 수량', 'column_type' => 'text', 'width' => '48px', 'sort_order' => 6], ['label' => '코일 사용량', 'column_type' => 'text', 'width' => '48px', 'sort_order' => 7], ['label' => '설치홈/부호', 'column_type' => 'text', 'width' => '56px', 'sort_order' => 8], ], ]; } // ─── 절곡 작업일지 ─── // React: BendingWorkLogContent.tsx // 결재: 작성/승인/승인/승인 (4단계) // 제품정보: 제품명, 재질, 마감, 유형 // 작업내역: 유형명, 세부품명, 재질, 입고&생산 LOT NO, 길이/규격, 수량 // 특수: 생산량 합계[kg] SUS/EGI private function bendingTemplate(): array { return [ 'name' => '절곡 작업일지', 'title' => '작업일지 (절곡)', 'approval_lines' => [ ['name' => '작성', 'dept' => '생산', 'role' => '담당자', 'sort_order' => 1], ['name' => '승인', 'dept' => '', 'role' => '승인자', 'sort_order' => 2], ['name' => '승인', 'dept' => '', 'role' => '승인자', 'sort_order' => 3], ['name' => '승인', 'dept' => '', 'role' => '승인자', 'sort_order' => 4], ], 'columns' => [ ['label' => '유형명', 'column_type' => 'text', 'width' => '100px', 'sort_order' => 1], ['label' => '세부품명', 'column_type' => 'text', 'width' => '100px', 'sort_order' => 2], ['label' => '재질', 'column_type' => 'text', 'width' => '60px', 'sort_order' => 3], ['label' => '입고 & 생산 LOT NO', 'column_type' => 'text', 'width' => '120px', 'sort_order' => 4], ['label' => '길이/규격', 'column_type' => 'text', 'width' => '80px', 'sort_order' => 5], ['label' => '수량', 'column_type' => 'text', 'width' => '60px', 'sort_order' => 6], ], ]; } /** * 기본정보 필드 (3종 공통: 신청업체 + 신청내용) * * 신청업체: 수주일, 수주처, 담당자, 연락처 * 신청내용: 현장명, 작업일자, 제품 LOT NO, 생산담당자, 출고예정일 */ private function createBasicFields(int $templateId): void { $fields = [ // 신청업체 ['label' => '수주일', 'field_type' => 'date', 'sort_order' => 1], ['label' => '수주처', 'field_type' => 'text', 'sort_order' => 2], ['label' => '담당자', 'field_type' => 'text', 'sort_order' => 3], ['label' => '연락처', 'field_type' => 'text', 'sort_order' => 4], // 신청내용 ['label' => '현장명', 'field_type' => 'text', 'sort_order' => 5], ['label' => '작업일자', 'field_type' => 'date', 'sort_order' => 6], ['label' => '제품 LOT NO', 'field_type' => 'text', 'sort_order' => 7], ['label' => '생산담당자', 'field_type' => 'text', 'sort_order' => 8], ['label' => '출고예정일', 'field_type' => 'date', 'sort_order' => 9], ]; foreach ($fields as $field) { DocumentTemplateBasicField::create(array_merge( ['template_id' => $templateId], $field, )); } } /** * 결재라인 (양식별 다름) */ private function createApprovalLines(int $templateId, array $lines): void { foreach ($lines as $line) { DocumentTemplateApprovalLine::create(array_merge( ['template_id' => $templateId], $line, )); } } /** * 데이터 테이블 컬럼 (양식별 다름) */ private function createColumns(int $templateId, array $columns): void { foreach ($columns as $col) { DocumentTemplateColumn::create(array_merge( ['template_id' => $templateId], $col, )); } } private function cleanupExisting(string $name): void { $existing = DocumentTemplate::where('tenant_id', $this->tenantId) ->where('name', $name) ->first(); if (! $existing) { return; } DocumentTemplateColumn::where('template_id', $existing->id)->delete(); DocumentTemplateBasicField::where('template_id', $existing->id)->delete(); DocumentTemplateApprovalLine::where('template_id', $existing->id)->delete(); $existing->forceDelete(); } }