feat: [receiving] 입고 성적서 파일 연결 기능 추가

- receivings 테이블에 certificate_file_id 컬럼 추가 (마이그레이션)
- Receiving 모델에 certificateFile 관계 및 fillable/casts 추가
- Store/Update Request에 certificate_file_id 검증 규칙 추가
- ReceivingService index/show에 certificateFile eager loading 추가
- store/update 시 certificate_file_id 저장 처리

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
유병철
2026-03-11 21:32:45 +09:00
parent 5828261dce
commit 2c9e5ae2da
5 changed files with 55 additions and 2 deletions

View File

@@ -31,6 +31,7 @@ public function rules(): array
'remark' => ['nullable', 'string', 'max:1000'],
'manufacturer' => ['nullable', 'string', 'max:100'],
'material_no' => ['nullable', 'string', 'max:50'],
'certificate_file_id' => ['nullable', 'integer', 'exists:files,id'],
];
}

View File

@@ -33,6 +33,7 @@ public function rules(): array
'inspection_result' => ['nullable', 'string', 'max:20'],
'manufacturer' => ['nullable', 'string', 'max:100'],
'material_no' => ['nullable', 'string', 'max:50'],
'certificate_file_id' => ['nullable', 'integer', 'exists:files,id'],
];
}

View File

@@ -34,6 +34,7 @@ class Receiving extends Model
'status',
'remark',
'options',
'certificate_file_id',
'created_by',
'updated_by',
'deleted_by',
@@ -47,6 +48,7 @@ class Receiving extends Model
'receiving_qty' => 'decimal:2',
'item_id' => 'integer',
'options' => 'array',
'certificate_file_id' => 'integer',
];
/**
@@ -92,6 +94,14 @@ public function item(): BelongsTo
return $this->belongsTo(\App\Models\Items\Item::class);
}
/**
* 업체 제공 성적서 파일 관계
*/
public function certificateFile(): BelongsTo
{
return $this->belongsTo(\App\Models\Commons\File::class, 'certificate_file_id');
}
/**
* 생성자 관계
*/

View File

@@ -16,7 +16,7 @@ public function index(array $params): LengthAwarePaginator
$tenantId = $this->tenantId();
$query = Receiving::query()
->with(['creator:id,name', 'item:id,item_type,code,name'])
->with(['creator:id,name', 'item:id,item_type,code,name', 'certificateFile:id,display_name,file_path'])
->where('tenant_id', $tenantId);
// 검색어 필터
@@ -162,7 +162,7 @@ public function show(int $id): Receiving
return Receiving::query()
->where('tenant_id', $tenantId)
->with(['creator:id,name', 'item:id,item_type,code,name'])
->with(['creator:id,name', 'item:id,item_type,code,name', 'certificateFile:id,display_name,file_path'])
->findOrFail($id);
}
@@ -203,6 +203,11 @@ public function store(array $data): Receiving
$receiving->status = $data['status'] ?? 'receiving_pending';
$receiving->remark = $data['remark'] ?? null;
// 성적서 파일 ID
if (isset($data['certificate_file_id'])) {
$receiving->certificate_file_id = $data['certificate_file_id'];
}
// options 필드 처리 (제조사, 수입검사 등 확장 필드)
$receiving->options = $this->buildOptions($data);
@@ -299,6 +304,11 @@ public function update(int $id, array $data): Receiving
}
}
// 성적서 파일 ID
if (array_key_exists('certificate_file_id', $data)) {
$receiving->certificate_file_id = $data['certificate_file_id'];
}
// options 필드 업데이트 (제조사, 수입검사 등 확장 필드)
$receiving->options = $this->mergeOptions($receiving->options, $data);

View File

@@ -0,0 +1,31 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::table('receivings', function (Blueprint $table) {
$table->unsignedBigInteger('certificate_file_id')
->nullable()
->after('options')
->comment('업체 제공 성적서 파일 ID');
$table->foreign('certificate_file_id')
->references('id')
->on('files')
->nullOnDelete();
});
}
public function down(): void
{
Schema::table('receivings', function (Blueprint $table) {
$table->dropForeign(['certificate_file_id']);
$table->dropColumn('certificate_file_id');
});
}
};