fix:문서 show/print 기본정보·종합판정·이미지 표시 수정
- 기본정보(bf_) 자동 backfill: show/print/edit 진입 시 bf_ 레코드 없으면 작업지시서 원본에서 resolve 후 저장 - 중간검사 DATA row 수를 section items → workOrderItems 기준으로 변경 - 종합판정: overall_result 없을 때 row_judgment에서 합격/불합격 자동 계산 fallback - 섹션 이미지: asset() → API 스토리지 URL 변환 (api.sam.kr/storage/tenants/...)
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Documents\Document;
|
||||
use App\Models\Documents\DocumentData;
|
||||
use App\Models\DocumentTemplate;
|
||||
use App\Models\Items\Item;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -100,6 +101,9 @@ public function edit(int $id): View|Response
|
||||
})->where('is_active', true)->orderBy('name')->get()
|
||||
: collect();
|
||||
|
||||
// 기본정보 bf_ 자동 backfill (show 안 거치고 바로 edit 진입 대비)
|
||||
$this->resolveAndBackfillBasicFields($document);
|
||||
|
||||
return view('documents.edit', [
|
||||
'document' => $document,
|
||||
'template' => $document->template,
|
||||
@@ -128,8 +132,26 @@ public function print(int $id): View
|
||||
'creator',
|
||||
])->where('tenant_id', $tenantId)->findOrFail($id);
|
||||
|
||||
// 연결된 작업지시서의 work_order_items 로드
|
||||
$workOrderItems = collect();
|
||||
if ($document->linkable_type === 'work_order' && $document->linkable_id) {
|
||||
$workOrderItems = DB::table('work_order_items')
|
||||
->where('work_order_id', $document->linkable_id)
|
||||
->orderBy('sort_order')
|
||||
->get()
|
||||
->map(function ($item) {
|
||||
$item->options = json_decode($item->options, true) ?? [];
|
||||
|
||||
return $item;
|
||||
});
|
||||
}
|
||||
|
||||
// 기본정보 bf_ 자동 backfill
|
||||
$this->resolveAndBackfillBasicFields($document);
|
||||
|
||||
return view('documents.print', [
|
||||
'document' => $document,
|
||||
'workOrderItems' => $workOrderItems,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -154,11 +176,119 @@ public function show(int $id): View
|
||||
'updater',
|
||||
])->where('tenant_id', $tenantId)->findOrFail($id);
|
||||
|
||||
// 연결된 작업지시서의 work_order_items 로드
|
||||
$workOrderItems = collect();
|
||||
if ($document->linkable_type === 'work_order' && $document->linkable_id) {
|
||||
$workOrderItems = DB::table('work_order_items')
|
||||
->where('work_order_id', $document->linkable_id)
|
||||
->orderBy('sort_order')
|
||||
->get()
|
||||
->map(function ($item) {
|
||||
$item->options = json_decode($item->options, true) ?? [];
|
||||
|
||||
return $item;
|
||||
});
|
||||
}
|
||||
|
||||
// 기본정보 bf_ 자동 backfill
|
||||
$this->resolveAndBackfillBasicFields($document);
|
||||
|
||||
return view('documents.show', [
|
||||
'document' => $document,
|
||||
'workOrderItems' => $workOrderItems,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 기본정보(bf_) 레코드가 없으면 원본 데이터에서 resolve → document_data에 저장
|
||||
* React resolveFieldValue와 동일 매핑 로직
|
||||
*/
|
||||
private function resolveAndBackfillBasicFields(Document $document): void
|
||||
{
|
||||
$basicFields = $document->template?->basicFields;
|
||||
if (! $basicFields || $basicFields->isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// bf_ 레코드가 하나라도 있으면 이미 저장된 것 → skip
|
||||
$existingBfCount = $document->data
|
||||
->filter(fn ($d) => str_starts_with($d->field_key, 'bf_'))
|
||||
->count();
|
||||
if ($existingBfCount > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 원본 데이터 로드: work_order + order
|
||||
if ($document->linkable_type !== 'work_order' || ! $document->linkable_id) {
|
||||
return;
|
||||
}
|
||||
|
||||
$workOrder = DB::table('work_orders')->find($document->linkable_id);
|
||||
if (! $workOrder) {
|
||||
return;
|
||||
}
|
||||
|
||||
$workOrderItems = DB::table('work_order_items')
|
||||
->where('work_order_id', $workOrder->id)
|
||||
->orderBy('sort_order')
|
||||
->get()
|
||||
->map(function ($item) {
|
||||
$item->options = json_decode($item->options, true) ?? [];
|
||||
|
||||
return $item;
|
||||
});
|
||||
|
||||
$order = $workOrder->sales_order_id
|
||||
? DB::table('orders')->find($workOrder->sales_order_id)
|
||||
: null;
|
||||
|
||||
// 검사자 정보: work_order_items[0].options.inspection_data.inspected_by
|
||||
$firstItem = $workOrderItems->first();
|
||||
$inspectionData = $firstItem?->options['inspection_data'] ?? [];
|
||||
$inspectedBy = $inspectionData['inspected_by'] ?? null;
|
||||
$inspectedAt = $inspectionData['inspected_at'] ?? null;
|
||||
$inspectorName = $inspectedBy
|
||||
? DB::table('users')->where('id', $inspectedBy)->value('name')
|
||||
: null;
|
||||
|
||||
// field_key → 값 매핑
|
||||
$resolveMap = [
|
||||
'product_name' => $firstItem?->item_name ?? '',
|
||||
'specification' => $firstItem?->specification ?? '',
|
||||
'lot_no' => $order?->order_no ?? '',
|
||||
'lot_size' => $workOrderItems->count().' 개소',
|
||||
'client' => $order?->client_name ?? '',
|
||||
'site_name' => $workOrder->project_name ?? '',
|
||||
'inspection_date' => $inspectedAt ? substr($inspectedAt, 0, 10) : now()->format('Y-m-d'),
|
||||
'inspector' => $inspectorName ?? '',
|
||||
];
|
||||
|
||||
// document_data에 bf_ 레코드 저장
|
||||
$records = [];
|
||||
foreach ($basicFields as $field) {
|
||||
$value = $resolveMap[$field->field_key] ?? $field->default_value ?? '';
|
||||
if ($value === '') {
|
||||
continue;
|
||||
}
|
||||
$records[] = [
|
||||
'document_id' => $document->id,
|
||||
'section_id' => null,
|
||||
'column_id' => null,
|
||||
'row_index' => 0,
|
||||
'field_key' => 'bf_'.$field->id,
|
||||
'field_value' => (string) $value,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
];
|
||||
}
|
||||
|
||||
if (! empty($records)) {
|
||||
DocumentData::insert($records);
|
||||
// 메모리의 data relation도 갱신
|
||||
$document->load('data');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 템플릿에 연결된 품목들의 규격 정보 (thickness, width, length) 조회
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user