feat(API): 검사 문서/성적서 연동 개선

- DocumentService: formatTemplateForReact 필드명 정합성 수정 (column_type, sub_labels, section title/image_path)
- WorkOrderService: process.options 로딩, 검사데이터 document_data 변환 로직 추가
- StoreItemInspectionRequest: templateValues 유효성 규칙 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-11 15:58:39 +09:00
parent a3a4e18e8a
commit 51aad4e522
3 changed files with 62 additions and 11 deletions

View File

@@ -53,7 +53,7 @@ public function index(array $params)
'team:id,name',
'salesOrder' => fn ($q) => $q->select('id', 'order_no', 'client_id', 'client_name', 'site_name', 'quantity', 'received_at', 'delivery_date')->withCount('rootNodes'),
'salesOrder.client:id,name',
'process:id,process_name,process_code,department',
'process:id,process_name,process_code,department,options',
'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,floor_code,symbol_code',
'items.sourceOrderItem.node:id,name,code',
@@ -208,7 +208,7 @@ public function show(int $id)
'salesOrder' => fn ($q) => $q->select('id', 'order_no', 'site_name', 'client_id', 'client_contact', 'received_at', 'writer_id', 'created_at', 'quantity')->withCount('rootNodes'),
'salesOrder.client:id,name',
'salesOrder.writer:id,name',
'process:id,process_name,process_code,work_steps,department',
'process:id,process_name,process_code,work_steps,department,options',
'process.steps' => fn ($q) => $q->where('is_active', true)->orderBy('sort_order'),
'items.sourceOrderItem:id,order_node_id,floor_code,symbol_code',
'items.sourceOrderItem.node:id,name,code',
@@ -1796,10 +1796,15 @@ public function createInspectionDocument(int $workOrderId, array $inspectionData
->latest()
->first();
// 프론트 InspectionData를 document_data 레코드 형식으로 변환
$documentDataRecords = $this->transformInspectionDataToDocumentRecords(
$inspectionData['data'] ?? []
);
if ($existingDocument) {
$document = $documentService->update($existingDocument->id, [
'title' => $inspectionData['title'] ?? $existingDocument->title,
'data' => $inspectionData['data'] ?? [],
'data' => $documentDataRecords,
]);
$action = 'inspection_document_updated';
@@ -1809,7 +1814,7 @@ public function createInspectionDocument(int $workOrderId, array $inspectionData
'title' => $inspectionData['title'] ?? "중간검사성적서 - {$workOrder->work_order_no}",
'linkable_type' => 'work_order',
'linkable_id' => $workOrderId,
'data' => $inspectionData['data'] ?? [],
'data' => $documentDataRecords,
'approvers' => $inspectionData['approvers'] ?? [],
];
@@ -1835,6 +1840,50 @@ public function createInspectionDocument(int $workOrderId, array $inspectionData
];
}
/**
* 프론트 InspectionData 배열을 document_data 레코드 형식으로 변환
*
* 프론트에서 보내는 형식:
* [{ productName, specification, judgment, nonConformingContent, templateValues: { section_X_item_Y: "ok"|number } }]
*
* document_data 테이블 형식:
* [{ field_key, field_value, row_index, section_id?, column_id? }]
*/
private function transformInspectionDataToDocumentRecords(array $rawItems): array
{
$records = [];
foreach ($rawItems as $rowIdx => $item) {
// templateValues의 각 키-값을 document_data 레코드로 변환
$templateValues = $item['templateValues'] ?? [];
foreach ($templateValues as $key => $value) {
$records[] = [
'field_key' => $key,
'field_value' => is_array($value) ? json_encode($value) : (string) $value,
'row_index' => $rowIdx,
];
}
// 판정, 부적합 내용 등 메타 필드도 저장
if (isset($item['judgment'])) {
$records[] = [
'field_key' => '_judgment',
'field_value' => (string) $item['judgment'],
'row_index' => $rowIdx,
];
}
if (! empty($item['nonConformingContent'])) {
$records[] = [
'field_key' => '_nonConformingContent',
'field_value' => (string) $item['nonConformingContent'],
'row_index' => $rowIdx,
];
}
}
return $records;
}
/**
* 작업지시 기본정보 빌드 (검사 문서 렌더링용)
*/