feat: 작업일지/중간검사 설정을 ProcessStep → Process 레벨로 이동
- Process 모델에 document_template_id, needs_work_log, work_log_template_id 추가 - ProcessStep에서 해당 필드 제거 - WorkOrderService의 검사 관련 3개 메서드(getInspectionTemplate, resolveInspectionDocument, createInspectionDocument) 공정 레벨 참조로 변경 - ProcessService eager loading에 documentTemplate, workLogTemplateRelation 추가 - FormRequest 검증 규칙 이동 (ProcessStep → Process) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -19,6 +19,9 @@ public function rules(): array
|
||||
'process_type' => ['required', 'string', 'in:생산,검사,포장,조립'],
|
||||
'department' => ['nullable', 'string', 'max:100'],
|
||||
'work_log_template' => ['nullable', 'string', 'max:100'],
|
||||
'document_template_id' => ['nullable', 'integer', 'exists:document_templates,id'],
|
||||
'needs_work_log' => ['nullable', 'boolean'],
|
||||
'work_log_template_id' => ['nullable', 'integer', 'exists:document_templates,id'],
|
||||
'required_workers' => ['nullable', 'integer', 'min:1'],
|
||||
'equipment_info' => ['nullable', 'string', 'max:255'],
|
||||
'work_steps' => ['nullable'],
|
||||
@@ -48,6 +51,9 @@ public function attributes(): array
|
||||
'process_type' => '공정구분',
|
||||
'department' => '담당부서',
|
||||
'work_log_template' => '작업일지 양식',
|
||||
'document_template_id' => '중간검사 양식',
|
||||
'needs_work_log' => '작업일지 여부',
|
||||
'work_log_template_id' => '작업일지 양식 ID',
|
||||
'required_workers' => '필요인원',
|
||||
'equipment_info' => '설비정보',
|
||||
'work_steps' => '작업단계',
|
||||
|
||||
@@ -19,6 +19,9 @@ public function rules(): array
|
||||
'process_type' => ['sometimes', 'required', 'string', 'in:생산,검사,포장,조립'],
|
||||
'department' => ['nullable', 'string', 'max:100'],
|
||||
'work_log_template' => ['nullable', 'string', 'max:100'],
|
||||
'document_template_id' => ['nullable', 'integer', 'exists:document_templates,id'],
|
||||
'needs_work_log' => ['nullable', 'boolean'],
|
||||
'work_log_template_id' => ['nullable', 'integer', 'exists:document_templates,id'],
|
||||
'required_workers' => ['nullable', 'integer', 'min:1'],
|
||||
'equipment_info' => ['nullable', 'string', 'max:255'],
|
||||
'work_steps' => ['nullable'],
|
||||
@@ -48,6 +51,9 @@ public function attributes(): array
|
||||
'process_type' => '공정구분',
|
||||
'department' => '담당부서',
|
||||
'work_log_template' => '작업일지 양식',
|
||||
'document_template_id' => '중간검사 양식',
|
||||
'needs_work_log' => '작업일지 여부',
|
||||
'work_log_template_id' => '작업일지 양식 ID',
|
||||
'required_workers' => '필요인원',
|
||||
'equipment_info' => '설비정보',
|
||||
'work_steps' => '작업단계',
|
||||
|
||||
@@ -18,7 +18,6 @@ public function rules(): array
|
||||
'is_required' => ['nullable', 'boolean'],
|
||||
'needs_approval' => ['nullable', 'boolean'],
|
||||
'needs_inspection' => ['nullable', 'boolean'],
|
||||
'document_template_id' => ['nullable', 'integer', 'exists:document_templates,id'],
|
||||
'is_active' => ['nullable', 'boolean'],
|
||||
'connection_type' => ['nullable', 'string', 'max:20'],
|
||||
'connection_target' => ['nullable', 'string', 'max:255'],
|
||||
@@ -33,7 +32,6 @@ public function attributes(): array
|
||||
'is_required' => '필수여부',
|
||||
'needs_approval' => '승인필요여부',
|
||||
'needs_inspection' => '검사필요여부',
|
||||
'document_template_id' => '문서양식',
|
||||
'is_active' => '사용여부',
|
||||
'connection_type' => '연결유형',
|
||||
'connection_target' => '연결대상',
|
||||
|
||||
@@ -18,7 +18,6 @@ public function rules(): array
|
||||
'is_required' => ['nullable', 'boolean'],
|
||||
'needs_approval' => ['nullable', 'boolean'],
|
||||
'needs_inspection' => ['nullable', 'boolean'],
|
||||
'document_template_id' => ['nullable', 'integer', 'exists:document_templates,id'],
|
||||
'is_active' => ['nullable', 'boolean'],
|
||||
'connection_type' => ['nullable', 'string', 'max:20'],
|
||||
'connection_target' => ['nullable', 'string', 'max:255'],
|
||||
@@ -33,7 +32,6 @@ public function attributes(): array
|
||||
'is_required' => '필수여부',
|
||||
'needs_approval' => '승인필요여부',
|
||||
'needs_inspection' => '검사필요여부',
|
||||
'document_template_id' => '문서양식',
|
||||
'is_active' => '사용여부',
|
||||
'connection_type' => '연결유형',
|
||||
'connection_target' => '연결대상',
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
use App\Traits\ModelTrait;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
@@ -26,6 +27,9 @@ class Process extends Model
|
||||
'process_type',
|
||||
'department',
|
||||
'work_log_template',
|
||||
'document_template_id',
|
||||
'needs_work_log',
|
||||
'work_log_template_id',
|
||||
'required_workers',
|
||||
'equipment_info',
|
||||
'work_steps',
|
||||
@@ -39,9 +43,26 @@ class Process extends Model
|
||||
protected $casts = [
|
||||
'work_steps' => 'array',
|
||||
'is_active' => 'boolean',
|
||||
'needs_work_log' => 'boolean',
|
||||
'required_workers' => 'integer',
|
||||
];
|
||||
|
||||
/**
|
||||
* 중간검사 양식
|
||||
*/
|
||||
public function documentTemplate(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Documents\DocumentTemplate::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 작업일지 양식 (관계명: work_log_template 컬럼과 충돌 방지)
|
||||
*/
|
||||
public function workLogTemplateRelation(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Documents\DocumentTemplate::class, 'work_log_template_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 공정 자동 분류 규칙 (패턴 규칙)
|
||||
*/
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Documents\DocumentTemplate;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
@@ -18,7 +17,6 @@ class ProcessStep extends Model
|
||||
'is_required',
|
||||
'needs_approval',
|
||||
'needs_inspection',
|
||||
'document_template_id',
|
||||
'is_active',
|
||||
'sort_order',
|
||||
'connection_type',
|
||||
@@ -41,12 +39,4 @@ public function process(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Process::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 문서 양식 (검사 시 사용할 템플릿)
|
||||
*/
|
||||
public function documentTemplate(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(DocumentTemplate::class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ public function index(array $params)
|
||||
|
||||
$query = Process::query()
|
||||
->where('tenant_id', $tenantId)
|
||||
->with(['classificationRules', 'processItems.item:id,code,name', 'steps']);
|
||||
->with(['classificationRules', 'processItems.item:id,code,name', 'steps', 'documentTemplate:id,name,category', 'workLogTemplateRelation:id,name,category']);
|
||||
|
||||
// 검색어
|
||||
if ($q !== '') {
|
||||
@@ -62,7 +62,7 @@ public function show(int $id)
|
||||
$tenantId = $this->tenantId();
|
||||
|
||||
$process = Process::where('tenant_id', $tenantId)
|
||||
->with(['classificationRules', 'processItems.item:id,code,name', 'steps'])
|
||||
->with(['classificationRules', 'processItems.item:id,code,name', 'steps', 'documentTemplate:id,name,category', 'workLogTemplateRelation:id,name,category'])
|
||||
->find($id);
|
||||
|
||||
if (! $process) {
|
||||
@@ -104,7 +104,7 @@ public function store(array $data)
|
||||
// 개별 품목 연결
|
||||
$this->syncProcessItems($process, $itemIds);
|
||||
|
||||
return $process->load(['classificationRules', 'processItems.item:id,code,name', 'steps']);
|
||||
return $process->load(['classificationRules', 'processItems.item:id,code,name', 'steps', 'documentTemplate:id,name,category', 'workLogTemplateRelation:id,name,category']);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -145,7 +145,7 @@ public function update(int $id, array $data)
|
||||
$this->syncProcessItems($process, $itemIds);
|
||||
}
|
||||
|
||||
return $process->fresh(['classificationRules', 'processItems.item:id,code,name', 'steps']);
|
||||
return $process->fresh(['classificationRules', 'processItems.item:id,code,name', 'steps', 'documentTemplate:id,name,category', 'workLogTemplateRelation:id,name,category']);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -201,7 +201,7 @@ public function toggleActive(int $id)
|
||||
'updated_by' => $userId,
|
||||
]);
|
||||
|
||||
return $process->fresh(['classificationRules', 'processItems.item:id,code,name', 'steps']);
|
||||
return $process->fresh(['classificationRules', 'processItems.item:id,code,name', 'steps', 'documentTemplate:id,name,category', 'workLogTemplateRelation:id,name,category']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,7 +17,7 @@ public function index(int $processId)
|
||||
$process = $this->findProcess($processId);
|
||||
|
||||
return $process->steps()
|
||||
->with('documentTemplate:id,name,category')
|
||||
->select('*')
|
||||
->orderBy('sort_order')
|
||||
->get();
|
||||
}
|
||||
@@ -30,7 +30,7 @@ public function show(int $processId, int $stepId)
|
||||
$this->findProcess($processId);
|
||||
|
||||
$step = ProcessStep::where('process_id', $processId)
|
||||
->with('documentTemplate:id,name,category')
|
||||
->select('*')
|
||||
->find($stepId);
|
||||
if (! $step) {
|
||||
throw new NotFoundHttpException(__('error.not_found'));
|
||||
|
||||
@@ -55,7 +55,7 @@ public function index(array $params)
|
||||
'salesOrder.client:id,name',
|
||||
'process:id,process_name,process_code,department',
|
||||
'items:id,work_order_id,item_id,item_name,specification,quantity,unit,status,options,sort_order,source_order_item_id',
|
||||
'items.sourceOrderItem:id,order_node_id',
|
||||
'items.sourceOrderItem:id,order_node_id,floor_code,symbol_code',
|
||||
'items.sourceOrderItem.node:id,name,code',
|
||||
]);
|
||||
|
||||
@@ -210,7 +210,7 @@ public function show(int $id)
|
||||
'salesOrder.writer:id,name',
|
||||
'process:id,process_name,process_code,work_steps,department',
|
||||
'process.steps' => fn ($q) => $q->where('is_active', true)->orderBy('sort_order'),
|
||||
'items.sourceOrderItem:id,order_node_id',
|
||||
'items.sourceOrderItem:id,order_node_id,floor_code,symbol_code',
|
||||
'items.sourceOrderItem.node:id,name,code',
|
||||
'bendingDetail',
|
||||
'issues' => fn ($q) => $q->orderByDesc('created_at'),
|
||||
@@ -257,9 +257,22 @@ public function store(array $data)
|
||||
|
||||
// 품목 저장: 직접 전달된 품목이 없고 수주 ID가 있으면 수주에서 복사
|
||||
if (empty($items) && $salesOrderId) {
|
||||
$salesOrder = \App\Models\Orders\Order::with('items')->find($salesOrderId);
|
||||
$salesOrder = \App\Models\Orders\Order::with('items.node')->find($salesOrderId);
|
||||
if ($salesOrder && $salesOrder->items->isNotEmpty()) {
|
||||
foreach ($salesOrder->items as $index => $orderItem) {
|
||||
// 수주 품목 + 노드에서 options 조합
|
||||
$nodeOptions = $orderItem->node?->options ?? [];
|
||||
$options = array_filter([
|
||||
'floor' => $orderItem->floor_code,
|
||||
'code' => $orderItem->symbol_code,
|
||||
'width' => $nodeOptions['width'] ?? $nodeOptions['open_width'] ?? null,
|
||||
'height' => $nodeOptions['height'] ?? $nodeOptions['open_height'] ?? null,
|
||||
'cutting_info' => $nodeOptions['cutting_info'] ?? null,
|
||||
'slat_info' => $nodeOptions['slat_info'] ?? null,
|
||||
'bending_info' => $nodeOptions['bending_info'] ?? null,
|
||||
'wip_info' => $nodeOptions['wip_info'] ?? null,
|
||||
], fn ($v) => $v !== null);
|
||||
|
||||
$workOrder->items()->create([
|
||||
'tenant_id' => $tenantId,
|
||||
'source_order_item_id' => $orderItem->id, // 원본 수주 품목 추적용
|
||||
@@ -269,6 +282,7 @@ public function store(array $data)
|
||||
'quantity' => $orderItem->quantity,
|
||||
'unit' => $orderItem->unit,
|
||||
'sort_order' => $index,
|
||||
'options' => ! empty($options) ? $options : null,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -1639,11 +1653,7 @@ public function getInspectionTemplate(int $workOrderId): array
|
||||
|
||||
$workOrder = WorkOrder::where('tenant_id', $tenantId)
|
||||
->with([
|
||||
'process.steps' => fn ($q) => $q->where('is_active', true)
|
||||
->where('needs_inspection', true)
|
||||
->whereNotNull('document_template_id')
|
||||
->orderBy('sort_order'),
|
||||
'process.steps.documentTemplate' => fn ($q) => $q->with([
|
||||
'process.documentTemplate' => fn ($q) => $q->with([
|
||||
'approvalLines',
|
||||
'basicFields',
|
||||
'sections.items',
|
||||
@@ -1659,8 +1669,10 @@ public function getInspectionTemplate(int $workOrderId): array
|
||||
throw new NotFoundHttpException(__('error.not_found'));
|
||||
}
|
||||
|
||||
$inspectionSteps = $workOrder->process?->steps ?? collect();
|
||||
if ($inspectionSteps->isEmpty()) {
|
||||
$process = $workOrder->process;
|
||||
$docTemplate = $process?->documentTemplate;
|
||||
|
||||
if (! $docTemplate) {
|
||||
return [
|
||||
'work_order_id' => $workOrderId,
|
||||
'has_template' => false,
|
||||
@@ -1671,28 +1683,17 @@ public function getInspectionTemplate(int $workOrderId): array
|
||||
}
|
||||
|
||||
$documentService = app(DocumentService::class);
|
||||
$templates = [];
|
||||
|
||||
foreach ($inspectionSteps as $step) {
|
||||
if (! $step->documentTemplate) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$templates[] = [
|
||||
'step_id' => $step->id,
|
||||
'step_name' => $step->step_name,
|
||||
'step_code' => $step->step_code,
|
||||
'sort_order' => $step->sort_order,
|
||||
'template' => $documentService->formatTemplateForReact($step->documentTemplate),
|
||||
];
|
||||
}
|
||||
$formattedTemplate = $documentService->formatTemplateForReact($docTemplate);
|
||||
|
||||
return [
|
||||
'work_order_id' => $workOrderId,
|
||||
'has_template' => ! empty($templates),
|
||||
'templates' => $templates,
|
||||
// 하위호환: 첫 번째 템플릿
|
||||
'template' => ! empty($templates) ? $templates[0]['template'] : null,
|
||||
'has_template' => true,
|
||||
'templates' => [[
|
||||
'template_id' => $docTemplate->id,
|
||||
'template_name' => $docTemplate->name,
|
||||
'template' => $formattedTemplate,
|
||||
]],
|
||||
'template' => $formattedTemplate,
|
||||
'work_order_info' => $this->buildWorkOrderInfo($workOrder),
|
||||
];
|
||||
}
|
||||
@@ -1709,11 +1710,7 @@ public function resolveInspectionDocument(int $workOrderId, array $params = []):
|
||||
|
||||
$workOrder = WorkOrder::where('tenant_id', $tenantId)
|
||||
->with([
|
||||
'process.steps' => fn ($q) => $q->where('is_active', true)
|
||||
->where('needs_inspection', true)
|
||||
->whereNotNull('document_template_id')
|
||||
->orderBy('sort_order'),
|
||||
'process.steps.documentTemplate' => fn ($q) => $q->with([
|
||||
'process.documentTemplate' => fn ($q) => $q->with([
|
||||
'approvalLines',
|
||||
'basicFields',
|
||||
'sections.items',
|
||||
@@ -1729,25 +1726,21 @@ public function resolveInspectionDocument(int $workOrderId, array $params = []):
|
||||
throw new NotFoundHttpException(__('error.not_found'));
|
||||
}
|
||||
|
||||
// step_id가 지정되면 해당 단계 사용, 아니면 첫 번째 검사 단계
|
||||
$inspectionSteps = $workOrder->process?->steps ?? collect();
|
||||
$stepId = $params['step_id'] ?? null;
|
||||
$process = $workOrder->process;
|
||||
$templateId = $process?->document_template_id;
|
||||
$docTemplate = $process?->documentTemplate;
|
||||
|
||||
$inspectionStep = $stepId
|
||||
? $inspectionSteps->firstWhere('id', (int) $stepId)
|
||||
: $inspectionSteps->first();
|
||||
|
||||
if (! $inspectionStep || ! $inspectionStep->document_template_id) {
|
||||
if (! $templateId || ! $docTemplate) {
|
||||
throw new BadRequestHttpException(__('error.work_order.no_inspection_template'));
|
||||
}
|
||||
|
||||
$documentService = app(DocumentService::class);
|
||||
$formattedTemplate = $documentService->formatTemplateForReact($inspectionStep->documentTemplate);
|
||||
$formattedTemplate = $documentService->formatTemplateForReact($docTemplate);
|
||||
|
||||
// 기존 문서 조회 (work_order + template, 수정 가능한 상태)
|
||||
$existingDocument = Document::query()
|
||||
->where('tenant_id', $tenantId)
|
||||
->where('template_id', $inspectionStep->document_template_id)
|
||||
->where('template_id', $templateId)
|
||||
->where('linkable_type', 'work_order')
|
||||
->where('linkable_id', $workOrderId)
|
||||
->whereIn('status', [Document::STATUS_DRAFT, Document::STATUS_REJECTED])
|
||||
@@ -1757,8 +1750,7 @@ public function resolveInspectionDocument(int $workOrderId, array $params = []):
|
||||
|
||||
return [
|
||||
'work_order_id' => $workOrderId,
|
||||
'step_id' => $inspectionStep->id,
|
||||
'step_name' => $inspectionStep->step_name,
|
||||
'template_id' => $templateId,
|
||||
'template' => $formattedTemplate,
|
||||
'existing_document' => $existingDocument,
|
||||
'work_order_info' => $this->buildWorkOrderInfo($workOrder),
|
||||
@@ -1768,7 +1760,7 @@ public function resolveInspectionDocument(int $workOrderId, array $params = []):
|
||||
/**
|
||||
* 검사 완료 시 Document + DocumentData 생성
|
||||
*
|
||||
* step_id 지정 시 해당 단계의 템플릿 사용, 미지정 시 첫 번째 검사 단계 사용.
|
||||
* 공정(Process) 레벨의 document_template_id를 사용.
|
||||
* 기존 DRAFT/REJECTED 문서가 있으면 update, 없으면 create.
|
||||
*/
|
||||
public function createInspectionDocument(int $workOrderId, array $inspectionData): array
|
||||
@@ -1777,27 +1769,18 @@ public function createInspectionDocument(int $workOrderId, array $inspectionData
|
||||
$userId = $this->apiUserId();
|
||||
|
||||
$workOrder = WorkOrder::where('tenant_id', $tenantId)
|
||||
->with([
|
||||
'process.steps' => fn ($q) => $q->where('is_active', true)
|
||||
->where('needs_inspection', true)
|
||||
->whereNotNull('document_template_id')
|
||||
->orderBy('sort_order'),
|
||||
])
|
||||
->with(['process'])
|
||||
->find($workOrderId);
|
||||
|
||||
if (! $workOrder) {
|
||||
throw new NotFoundHttpException(__('error.not_found'));
|
||||
}
|
||||
|
||||
// step_id가 지정되면 해당 단계 사용, 아니면 첫 번째
|
||||
$inspectionSteps = $workOrder->process?->steps ?? collect();
|
||||
$stepId = $inspectionData['step_id'] ?? null;
|
||||
// 공정 레벨의 중간검사 양식 사용
|
||||
$process = $workOrder->process;
|
||||
$templateId = $process?->document_template_id;
|
||||
|
||||
$inspectionStep = $stepId
|
||||
? $inspectionSteps->firstWhere('id', (int) $stepId)
|
||||
: $inspectionSteps->first();
|
||||
|
||||
if (! $inspectionStep || ! $inspectionStep->document_template_id) {
|
||||
if (! $templateId) {
|
||||
throw new BadRequestHttpException(__('error.work_order.no_inspection_template'));
|
||||
}
|
||||
|
||||
@@ -1806,7 +1789,7 @@ public function createInspectionDocument(int $workOrderId, array $inspectionData
|
||||
// 기존 DRAFT/REJECTED 문서가 있으면 update
|
||||
$existingDocument = Document::query()
|
||||
->where('tenant_id', $tenantId)
|
||||
->where('template_id', $inspectionStep->document_template_id)
|
||||
->where('template_id', $templateId)
|
||||
->where('linkable_type', 'work_order')
|
||||
->where('linkable_id', $workOrderId)
|
||||
->whereIn('status', [Document::STATUS_DRAFT, Document::STATUS_REJECTED])
|
||||
@@ -1822,7 +1805,7 @@ public function createInspectionDocument(int $workOrderId, array $inspectionData
|
||||
$action = 'inspection_document_updated';
|
||||
} else {
|
||||
$documentData = [
|
||||
'template_id' => $inspectionStep->document_template_id,
|
||||
'template_id' => $templateId,
|
||||
'title' => $inspectionData['title'] ?? "중간검사성적서 - {$workOrder->work_order_no}",
|
||||
'linkable_type' => 'work_order',
|
||||
'linkable_id' => $workOrderId,
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
/**
|
||||
* 검사양식/작업일지 설정을 ProcessStep → Process 레벨로 이동
|
||||
* - processes: document_template_id, needs_work_log, work_log_template_id 추가
|
||||
* - process_steps: document_template_id 제거
|
||||
*/
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
// 1. Process에 검사양식/작업일지 필드 추가
|
||||
Schema::table('processes', function (Blueprint $table) {
|
||||
$table->foreignId('document_template_id')->nullable()->after('work_log_template')
|
||||
->constrained('document_templates')->nullOnDelete()->comment('중간검사 양식 ID');
|
||||
$table->boolean('needs_work_log')->default(false)->after('document_template_id')->comment('작업일지 여부');
|
||||
$table->foreignId('work_log_template_id')->nullable()->after('needs_work_log')
|
||||
->constrained('document_templates')->nullOnDelete()->comment('작업일지 양식 ID');
|
||||
});
|
||||
|
||||
// 2. ProcessStep에서 document_template_id 제거
|
||||
Schema::table('process_steps', function (Blueprint $table) {
|
||||
$table->dropForeign(['document_template_id']);
|
||||
$table->dropColumn('document_template_id');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
// ProcessStep에 document_template_id 복원
|
||||
Schema::table('process_steps', function (Blueprint $table) {
|
||||
$table->foreignId('document_template_id')->nullable()->after('needs_inspection')
|
||||
->constrained('document_templates')->nullOnDelete();
|
||||
});
|
||||
|
||||
// Process에서 필드 제거
|
||||
Schema::table('processes', function (Blueprint $table) {
|
||||
$table->dropForeign(['work_log_template_id']);
|
||||
$table->dropForeign(['document_template_id']);
|
||||
$table->dropColumn(['work_log_template_id', 'needs_work_log', 'document_template_id']);
|
||||
});
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user