diff --git a/app/Http/Controllers/Api/Admin/DocumentTemplateApiController.php b/app/Http/Controllers/Api/Admin/DocumentTemplateApiController.php index b48c43ad..a05462c2 100644 --- a/app/Http/Controllers/Api/Admin/DocumentTemplateApiController.php +++ b/app/Http/Controllers/Api/Admin/DocumentTemplateApiController.php @@ -617,19 +617,18 @@ public function getCommonCodes(string $group): JsonResponse } /** - * 관계 데이터 저장 + * 관계 데이터 저장 (ID 보존 upsert 방식) + * + * sections/columns는 기존 ID를 보존하여 document_data 참조가 깨지지 않도록 함. + * 나머지(approval_lines, basic_fields 등)는 단순 관계라 삭제→재생성. */ private function saveRelations(DocumentTemplate $template, array $data, bool $deleteExisting = false): void { - // 기존 데이터 삭제 (수정 시) + // 단순 관계: 삭제 → 재생성 (document_data가 참조하지 않는 테이블) if ($deleteExisting) { $template->approvalLines()->delete(); $template->basicFields()->delete(); - // sections는 cascade로 items도 함께 삭제됨 - $template->sections()->delete(); - $template->columns()->delete(); $template->sectionFields()->delete(); - // links는 cascade로 linkValues도 함께 삭제됨 $template->links()->delete(); } @@ -661,20 +660,42 @@ private function saveRelations(DocumentTemplate $template, array $data, bool $de } } - // 섹션 및 항목 - if (! empty($data['sections'])) { + // 섹션 및 항목: ID 보존 upsert (document_data.section_id 참조 보호) + if (isset($data['sections'])) { + $incomingIds = collect($data['sections'])->pluck('id')->filter()->toArray(); + // 요청에 없는 섹션만 삭제 (cascade로 items도 삭제) + if ($deleteExisting) { + $template->sections()->whereNotIn('id', $incomingIds)->each(function ($section) { + $section->items()->delete(); + $section->delete(); + }); + } + foreach ($data['sections'] as $sIndex => $section) { - $newSection = DocumentTemplateSection::create([ - 'template_id' => $template->id, + $sectionData = [ 'title' => $section['title'] ?? '', 'image_path' => $section['image_path'] ?? null, 'sort_order' => $sIndex, - ]); + ]; + + if (! empty($section['id']) && $template->sections()->where('id', $section['id'])->exists()) { + $existing = $template->sections()->where('id', $section['id'])->first(); + $existing->update($sectionData); + $savedSection = $existing; + } else { + $savedSection = DocumentTemplateSection::create(array_merge( + ['template_id' => $template->id], + $sectionData + )); + } + + // 섹션 항목 upsert + if (isset($section['items'])) { + $itemIncomingIds = collect($section['items'])->pluck('id')->filter()->toArray(); + $savedSection->items()->whereNotIn('id', $itemIncomingIds)->delete(); - if (! empty($section['items'])) { foreach ($section['items'] as $iIndex => $item) { - DocumentTemplateSectionItem::create([ - 'section_id' => $newSection->id, + $itemData = [ 'category' => $item['category'] ?? '', 'item' => $item['item'] ?? '', 'standard' => $item['standard'] ?? '', @@ -688,24 +709,46 @@ private function saveRelations(DocumentTemplate $template, array $data, bool $de 'regulation' => $item['regulation'] ?? '', 'field_values' => $item['field_values'] ?? null, 'sort_order' => $iIndex, - ]); + ]; + + if (! empty($item['id']) && $savedSection->items()->where('id', $item['id'])->exists()) { + $savedSection->items()->where('id', $item['id'])->update($itemData); + } else { + DocumentTemplateSectionItem::create(array_merge( + ['section_id' => $savedSection->id], + $itemData + )); + } } } } } - // 컬럼 - if (! empty($data['columns'])) { + // 컬럼: ID 보존 upsert (document_data.column_id 참조 보호) + if (isset($data['columns'])) { + $incomingIds = collect($data['columns'])->pluck('id')->filter()->toArray(); + if ($deleteExisting) { + $template->columns()->whereNotIn('id', $incomingIds)->delete(); + } + foreach ($data['columns'] as $index => $column) { - DocumentTemplateColumn::create([ - 'template_id' => $template->id, + $colData = [ 'label' => $column['label'] ?? '', 'width' => $column['width'] ?? '100px', 'column_type' => $column['column_type'] ?? 'text', 'group_name' => $column['group_name'] ?? null, 'sub_labels' => $column['sub_labels'] ?? null, 'sort_order' => $index, - ]); + ]; + + if (! empty($column['id']) && $template->columns()->where('id', $column['id'])->exists()) { + $template->columns()->where('id', $column['id'])->update($colData); + } else { + DocumentTemplateColumn::create(array_merge( + ['template_id' => $template->id], + $colData + )); + } } }