From b3891e93b7c3622bc4e0a6606909a0dc73c69ab0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B6=8C=ED=98=81=EC=84=B1?= Date: Thu, 12 Feb 2026 00:01:37 +0900 Subject: [PATCH] =?UTF-8?q?feat(MNG):=EC=9E=91=EC=97=85=EC=9D=BC=EC=A7=80?= =?UTF-8?q?=20=EC=96=91=EC=8B=9D=20=EC=8B=9C=EB=8D=94=203=EC=A2=85=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - WorkLogTemplateSeeder: 스크린/슬랫/절곡 공정별 작업일지 양식 - 공정별 결재라인, 기본필드(9개), 컬럼 구조 반영 - 판정 없음, 비고만 사용 Co-Authored-By: Claude Opus 4.6 --- database/seeders/WorkLogTemplateSeeder.php | 230 +++++++++++++++++++++ 1 file changed, 230 insertions(+) create mode 100644 database/seeders/WorkLogTemplateSeeder.php diff --git a/database/seeders/WorkLogTemplateSeeder.php b/database/seeders/WorkLogTemplateSeeder.php new file mode 100644 index 00000000..6471f94e --- /dev/null +++ b/database/seeders/WorkLogTemplateSeeder.php @@ -0,0 +1,230 @@ +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(); + } +}