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:
@@ -37,6 +37,8 @@ public function rules(): array
|
|||||||
'inspection_data.gapPoints.*.right' => 'nullable|numeric',
|
'inspection_data.gapPoints.*.right' => 'nullable|numeric',
|
||||||
'inspection_data.judgment' => ['nullable', Rule::in(['pass', 'fail'])],
|
'inspection_data.judgment' => ['nullable', Rule::in(['pass', 'fail'])],
|
||||||
'inspection_data.nonConformingContent' => 'nullable|string|max:1000',
|
'inspection_data.nonConformingContent' => 'nullable|string|max:1000',
|
||||||
|
'inspection_data.templateValues' => 'nullable|array',
|
||||||
|
'inspection_data.templateValues.*' => 'nullable',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -646,10 +646,8 @@ public function formatTemplateForReact(DocumentTemplate $template): array
|
|||||||
'id' => $field->id,
|
'id' => $field->id,
|
||||||
'field_key' => $field->field_key,
|
'field_key' => $field->field_key,
|
||||||
'label' => $field->label,
|
'label' => $field->label,
|
||||||
'input_type' => $field->input_type,
|
'field_type' => $field->field_type,
|
||||||
'options' => $field->options,
|
|
||||||
'default_value' => $field->default_value,
|
'default_value' => $field->default_value,
|
||||||
'is_required' => $field->is_required,
|
|
||||||
'sort_order' => $field->sort_order,
|
'sort_order' => $field->sort_order,
|
||||||
])->toArray(),
|
])->toArray(),
|
||||||
'section_fields' => $template->sectionFields->map(fn ($field) => [
|
'section_fields' => $template->sectionFields->map(fn ($field) => [
|
||||||
@@ -664,7 +662,9 @@ public function formatTemplateForReact(DocumentTemplate $template): array
|
|||||||
])->toArray(),
|
])->toArray(),
|
||||||
'sections' => $template->sections->map(fn ($section) => [
|
'sections' => $template->sections->map(fn ($section) => [
|
||||||
'id' => $section->id,
|
'id' => $section->id,
|
||||||
'name' => $section->name,
|
'name' => $section->title,
|
||||||
|
'title' => $section->title,
|
||||||
|
'image_path' => $section->image_path,
|
||||||
'sort_order' => $section->sort_order,
|
'sort_order' => $section->sort_order,
|
||||||
'items' => $section->items->map(function ($item) use ($methodCodes) {
|
'items' => $section->items->map(function ($item) use ($methodCodes) {
|
||||||
// method 코드를 한글 이름으로 변환
|
// method 코드를 한글 이름으로 변환
|
||||||
@@ -693,10 +693,10 @@ public function formatTemplateForReact(DocumentTemplate $template): array
|
|||||||
'columns' => $template->columns->map(fn ($col) => [
|
'columns' => $template->columns->map(fn ($col) => [
|
||||||
'id' => $col->id,
|
'id' => $col->id,
|
||||||
'label' => $col->label,
|
'label' => $col->label,
|
||||||
'input_type' => $col->input_type,
|
'column_type' => $col->column_type,
|
||||||
'options' => $col->options,
|
'sub_labels' => $col->sub_labels,
|
||||||
|
'group_name' => $col->group_name,
|
||||||
'width' => $col->width,
|
'width' => $col->width,
|
||||||
'is_required' => $col->is_required,
|
|
||||||
'sort_order' => $col->sort_order,
|
'sort_order' => $col->sort_order,
|
||||||
])->toArray(),
|
])->toArray(),
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public function index(array $params)
|
|||||||
'team:id,name',
|
'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' => fn ($q) => $q->select('id', 'order_no', 'client_id', 'client_name', 'site_name', 'quantity', 'received_at', 'delivery_date')->withCount('rootNodes'),
|
||||||
'salesOrder.client:id,name',
|
'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: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:id,order_node_id,floor_code,symbol_code',
|
||||||
'items.sourceOrderItem.node:id,name,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' => 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.client:id,name',
|
||||||
'salesOrder.writer: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'),
|
'process.steps' => fn ($q) => $q->where('is_active', true)->orderBy('sort_order'),
|
||||||
'items.sourceOrderItem:id,order_node_id,floor_code,symbol_code',
|
'items.sourceOrderItem:id,order_node_id,floor_code,symbol_code',
|
||||||
'items.sourceOrderItem.node:id,name,code',
|
'items.sourceOrderItem.node:id,name,code',
|
||||||
@@ -1796,10 +1796,15 @@ public function createInspectionDocument(int $workOrderId, array $inspectionData
|
|||||||
->latest()
|
->latest()
|
||||||
->first();
|
->first();
|
||||||
|
|
||||||
|
// 프론트 InspectionData를 document_data 레코드 형식으로 변환
|
||||||
|
$documentDataRecords = $this->transformInspectionDataToDocumentRecords(
|
||||||
|
$inspectionData['data'] ?? []
|
||||||
|
);
|
||||||
|
|
||||||
if ($existingDocument) {
|
if ($existingDocument) {
|
||||||
$document = $documentService->update($existingDocument->id, [
|
$document = $documentService->update($existingDocument->id, [
|
||||||
'title' => $inspectionData['title'] ?? $existingDocument->title,
|
'title' => $inspectionData['title'] ?? $existingDocument->title,
|
||||||
'data' => $inspectionData['data'] ?? [],
|
'data' => $documentDataRecords,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$action = 'inspection_document_updated';
|
$action = 'inspection_document_updated';
|
||||||
@@ -1809,7 +1814,7 @@ public function createInspectionDocument(int $workOrderId, array $inspectionData
|
|||||||
'title' => $inspectionData['title'] ?? "중간검사성적서 - {$workOrder->work_order_no}",
|
'title' => $inspectionData['title'] ?? "중간검사성적서 - {$workOrder->work_order_no}",
|
||||||
'linkable_type' => 'work_order',
|
'linkable_type' => 'work_order',
|
||||||
'linkable_id' => $workOrderId,
|
'linkable_id' => $workOrderId,
|
||||||
'data' => $inspectionData['data'] ?? [],
|
'data' => $documentDataRecords,
|
||||||
'approvers' => $inspectionData['approvers'] ?? [],
|
'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;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 작업지시 기본정보 빌드 (검사 문서 렌더링용)
|
* 작업지시 기본정보 빌드 (검사 문서 렌더링용)
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user