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); $this->createBasicFields($template->id); foreach ($def['sections'] as $i => $sectionDef) { $this->createSection($template->id, $sectionDef['title'], $sectionDef['items'], $i + 1); } $this->createColumns($template->id, $def['columns']); $this->command->info("✅ {$def['name']} (ID: {$template->id})"); } } private function getTemplateDefinitions(): array { return [ $this->jointbarTemplate(), $this->slatTemplate(), $this->screenTemplate(), $this->bendingTemplate(), ]; } // ─── 조인트바 (가장 단순: 단일 행, 고정 기준값) ─── private function jointbarTemplate(): array { return [ 'name' => '조인트바 중간검사 성적서', 'title' => '조인트바 - 중간 검사 성적서', 'sections' => [ [ 'title' => '중간검사 기준서', 'items' => [], ], [ 'title' => '중간검사 DATA', 'items' => [ [ 'category' => '겉모양', 'item' => '가공상태', 'standard' => '양호/불량', 'method' => '육안검사', 'frequency' => '전수', ], [ 'category' => '겉모양', 'item' => '조립상태', 'standard' => '양호/불량', 'method' => '육안검사', 'frequency' => '전수', ], [ 'category' => '치수', 'item' => '① 높이', 'standard' => '16.5 ± 1mm', 'method' => '계측검사', 'frequency' => '전수', ], [ 'category' => '치수', 'item' => '② 높이', 'standard' => '14.5 ± 1mm', 'method' => '계측검사', 'frequency' => '전수', ], [ 'category' => '치수', 'item' => '③ 길이 (엔드락제외)', 'standard' => '300 ± 4mm', 'method' => '계측검사', 'frequency' => '전수', ], [ 'category' => '치수', 'item' => '④ 간격', 'standard' => '150 ± 4mm', 'method' => '계측검사', 'frequency' => '전수', ], ], ], ], 'columns' => [ ['label' => '일련번호', 'column_type' => 'text', 'width' => '80px', 'sort_order' => 1], ['label' => '가공상태', 'column_type' => 'check', 'width' => '80px', 'sort_order' => 2], ['label' => '조립상태', 'column_type' => 'check', 'width' => '80px', 'sort_order' => 3], [ 'label' => '① 높이', 'column_type' => 'complex', 'group_name' => '① 높이', 'sub_labels' => ['기준(16.5±1)', '측정값'], 'width' => '160px', 'sort_order' => 4, ], [ 'label' => '② 높이', 'column_type' => 'complex', 'group_name' => '② 높이', 'sub_labels' => ['기준(14.5±1)', '측정값'], 'width' => '160px', 'sort_order' => 5, ], [ 'label' => '③ 길이', 'column_type' => 'complex', 'group_name' => '③ 길이', 'sub_labels' => ['기준(300±4)', '측정값'], 'width' => '160px', 'sort_order' => 6, ], [ 'label' => '④ 간격', 'column_type' => 'complex', 'group_name' => '④ 간격', 'sub_labels' => ['기준(150±4)', '측정값'], 'width' => '160px', 'sort_order' => 7, ], ['label' => '판정 (적/부)', 'column_type' => 'select', 'width' => '80px', 'sort_order' => 8], ], ]; } // ─── 슬랫 (고정 기준값 2개 + 도면치수 1개) ─── private function slatTemplate(): array { return [ 'name' => '슬랫 중간검사 성적서', 'title' => '슬랫 - 중간 검사 성적서', 'sections' => [ [ 'title' => '중간검사 기준서', 'items' => [], ], [ 'title' => '중간검사 DATA', 'items' => [ [ 'category' => '겉모양', 'item' => '가공상태', 'standard' => '양호/불량', 'method' => '육안검사', 'frequency' => '전수', ], [ 'category' => '겉모양', 'item' => '조립상태', 'standard' => '양호/불량', 'method' => '육안검사', 'frequency' => '전수', ], [ 'category' => '치수', 'item' => '① 높이', 'standard' => '16.5 ± 1mm', 'method' => '계측검사', 'frequency' => '전수', ], [ 'category' => '치수', 'item' => '② 높이', 'standard' => '14.5 ± 1mm', 'method' => '계측검사', 'frequency' => '전수', ], [ 'category' => '치수', 'item' => '③ 길이 (엔드락제외)', 'standard' => '도면치수 ± 4mm', 'method' => '계측검사', 'frequency' => '전수', ], ], ], ], 'columns' => [ ['label' => '일련번호', 'column_type' => 'text', 'width' => '80px', 'sort_order' => 1], ['label' => '가공상태', 'column_type' => 'check', 'width' => '80px', 'sort_order' => 2], ['label' => '조립상태', 'column_type' => 'check', 'width' => '80px', 'sort_order' => 3], [ 'label' => '① 높이', 'column_type' => 'complex', 'group_name' => '① 높이', 'sub_labels' => ['기준(16.5±1)', '측정값'], 'width' => '160px', 'sort_order' => 4, ], [ 'label' => '② 높이', 'column_type' => 'complex', 'group_name' => '② 높이', 'sub_labels' => ['기준(14.5±1)', '측정값'], 'width' => '160px', 'sort_order' => 5, ], [ 'label' => '③ 길이', 'column_type' => 'complex', 'group_name' => '③ 길이', 'sub_labels' => ['도면치수', '측정값'], 'width' => '160px', 'sort_order' => 6, ], ['label' => '판정 (적/부)', 'column_type' => 'select', 'width' => '80px', 'sort_order' => 7], ], ]; } // ─── 스크린 (겉모양 3개 + 치수 3개) ─── private function screenTemplate(): array { return [ 'name' => '스크린 중간검사 성적서', 'title' => '스크린 - 중간 검사 성적서', 'sections' => [ [ 'title' => '중간검사 기준서', 'items' => [], ], [ 'title' => '중간검사 DATA', 'items' => [ [ 'category' => '겉모양', 'item' => '가공상태', 'standard' => '양호/불량', 'method' => '육안검사', 'frequency' => '전수', ], [ 'category' => '겉모양', 'item' => '재봉상태', 'standard' => '양호/불량', 'method' => '육안검사', 'frequency' => '전수', ], [ 'category' => '겉모양', 'item' => '조립상태', 'standard' => '양호/불량', 'method' => '육안검사', 'frequency' => '전수', ], [ 'category' => '치수', 'item' => '① 길이', 'standard' => '도면치수 ± 4mm', 'method' => '계측검사', 'frequency' => '전수', ], [ 'category' => '치수', 'item' => '② 높이', 'standard' => '도면치수 ± 40mm', 'method' => '계측검사', 'frequency' => '전수', ], [ 'category' => '치수', 'item' => '③ 간격', 'standard' => '400 이하', 'method' => '체크검사', 'frequency' => '전수', ], ], ], ], 'columns' => [ ['label' => '일련번호', 'column_type' => 'text', 'width' => '80px', 'sort_order' => 1], ['label' => '가공상태', 'column_type' => 'check', 'width' => '80px', 'sort_order' => 2], ['label' => '재봉상태', 'column_type' => 'check', 'width' => '80px', 'sort_order' => 3], ['label' => '조립상태', 'column_type' => 'check', 'width' => '80px', 'sort_order' => 4], [ 'label' => '① 길이', 'column_type' => 'complex', 'group_name' => '① 길이', 'sub_labels' => ['도면치수', '측정값'], 'width' => '160px', 'sort_order' => 5, ], [ 'label' => '② 높이', 'column_type' => 'complex', 'group_name' => '② 높이', 'sub_labels' => ['도면치수', '측정값'], 'width' => '160px', 'sort_order' => 6, ], [ 'label' => '③ 간격', 'column_type' => 'complex', 'group_name' => '③ 간격', 'sub_labels' => ['기준(400이하)', 'OK/NG'], 'width' => '160px', 'sort_order' => 7, ], ['label' => '판정 (적/부)', 'column_type' => 'select', 'width' => '80px', 'sort_order' => 8], ], ]; } // ─── 절곡품 (가장 복잡: 구성품별 다른 검사항목) ─── private function bendingTemplate(): array { return [ 'name' => '절곡품 중간검사 성적서', 'title' => '절곡품 - 중간 검사 성적서', 'sections' => [ [ 'title' => '중간검사 기준서', 'items' => [], ], [ 'title' => '중간검사 DATA', 'items' => [ // 가이드레일 ['category' => '가이드레일/겉모양', 'item' => '절곡상태', 'standard' => '양호/불량', 'method' => '육안검사', 'frequency' => '전수'], ['category' => '가이드레일/치수', 'item' => '길이', 'standard' => '도면치수 ± 4mm', 'method' => '계측검사', 'frequency' => '전수'], ['category' => '가이드레일/치수', 'item' => '너비', 'standard' => '도면치수 ± 4mm', 'method' => '계측검사', 'frequency' => '전수'], ['category' => '가이드레일/치수', 'item' => '간격 (POINT별)', 'standard' => '도면치수 ± 2mm (벽면형 4P, 측면형 6P)', 'method' => '계측검사', 'frequency' => '전수'], // 하단마감재 ['category' => '하단마감재/겉모양', 'item' => '절곡상태', 'standard' => '양호/불량', 'method' => '육안검사', 'frequency' => '전수'], ['category' => '하단마감재/치수', 'item' => '너비', 'standard' => '60mm 기준', 'method' => '계측검사', 'frequency' => '전수'], // 케이스(셔터박스) ['category' => '케이스/겉모양', 'item' => '절곡상태', 'standard' => '양호/불량', 'method' => '육안검사', 'frequency' => '전수'], ['category' => '케이스/치수', 'item' => '높이/하단/너비차/위치', 'standard' => '도면치수 기준 (양면/밑면/후면)', 'method' => '계측검사', 'frequency' => '전수'], // 하단 L-BAR / 연기차단재 ['category' => 'L-BAR·연기차단재/치수', 'item' => 'L-BAR 너비', 'standard' => '17mm 기준', 'method' => '계측검사', 'frequency' => '전수'], ['category' => 'L-BAR·연기차단재/치수', 'item' => '연기차단재 (가이드레일용)', 'standard' => '너비 50mm, 간격 12mm', 'method' => '계측검사', 'frequency' => '전수'], ['category' => 'L-BAR·연기차단재/치수', 'item' => '연기차단재 (케이스용)', 'standard' => '너비 80mm, 간격 12mm', 'method' => '계측검사', 'frequency' => '전수'], ], ], ], 'columns' => [ ['label' => '분류/제품명', 'column_type' => 'text', 'width' => '120px', 'sort_order' => 1], ['label' => '타입', 'column_type' => 'text', 'width' => '100px', 'sort_order' => 2], ['label' => '겉모양(절곡상태)', 'column_type' => 'check', 'width' => '80px', 'sort_order' => 3], [ 'label' => '길이', 'column_type' => 'complex', 'group_name' => '길이', 'sub_labels' => ['도면치수', '측정값'], 'width' => '160px', 'sort_order' => 4, ], [ 'label' => '너비', 'column_type' => 'complex', 'group_name' => '너비', 'sub_labels' => ['도면치수', '측정값'], 'width' => '160px', 'sort_order' => 5, ], [ 'label' => '간격', 'column_type' => 'complex', 'group_name' => '간격', 'sub_labels' => ['POINT', '도면치수', '측정값'], 'width' => '240px', 'sort_order' => 6, ], ['label' => '판정 (적/부)', 'column_type' => 'select', 'width' => '80px', 'sort_order' => 7], ], ]; } /** * 결재라인: 작성(판매) / 검토(생산) / 승인(품질) - 5130 중간검사 공통 */ private function createApprovalLines(int $templateId): void { $lines = [ ['name' => '작성', 'dept' => '판매', 'role' => '담당자', 'sort_order' => 1], ['name' => '검토', 'dept' => '생산', 'role' => '담당자', 'sort_order' => 2], ['name' => '승인', 'dept' => '품질', 'role' => 'QC', 'sort_order' => 3], ]; foreach ($lines as $line) { DocumentTemplateApprovalLine::create(array_merge( ['template_id' => $templateId], $line, )); } } /** * 기본정보 필드 (중간검사 공통) */ private function createBasicFields(int $templateId): void { $fields = [ ['label' => '품명', 'field_type' => 'text', 'sort_order' => 1], ['label' => '규격', 'field_type' => 'text', 'sort_order' => 2], ['label' => '수주 LOT NO', 'field_type' => 'text', 'sort_order' => 3], ['label' => '로트크기', 'field_type' => 'text', 'sort_order' => 4], ['label' => '발주처', 'field_type' => 'text', 'sort_order' => 5], ['label' => '현장명', 'field_type' => 'text', 'sort_order' => 6], ['label' => '검사일자', 'field_type' => 'date', 'sort_order' => 7], ['label' => '검사자', 'field_type' => 'text', 'sort_order' => 8], ]; foreach ($fields as $field) { DocumentTemplateBasicField::create(array_merge( ['template_id' => $templateId], $field, )); } } /** * 검사 섹션 + 항목 */ private function createSection(int $templateId, string $title, array $items, int $sortOrder): void { $section = DocumentTemplateSection::create([ 'template_id' => $templateId, 'title' => $title, 'sort_order' => $sortOrder, ]); foreach ($items as $i => $item) { DocumentTemplateSectionItem::create(array_merge( ['section_id' => $section->id, 'sort_order' => $i + 1], $item, )); } } /** * 데이터 테이블 컬럼 (양식별 다름) */ 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(); $sections = DocumentTemplateSection::where('template_id', $existing->id)->get(); foreach ($sections as $section) { DocumentTemplateSectionItem::where('section_id', $section->id)->delete(); } DocumentTemplateSection::where('template_id', $existing->id)->delete(); DocumentTemplateBasicField::where('template_id', $existing->id)->delete(); DocumentTemplateApprovalLine::where('template_id', $existing->id)->delete(); $existing->forceDelete(); } }