From 2c9e5ae2da8089353392fc4667ce25b9cb3a26be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9C=A0=EB=B3=91=EC=B2=A0?= Date: Wed, 11 Mar 2026 21:32:45 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20[receiving]=20=EC=9E=85=EA=B3=A0=20?= =?UTF-8?q?=EC=84=B1=EC=A0=81=EC=84=9C=20=ED=8C=8C=EC=9D=BC=20=EC=97=B0?= =?UTF-8?q?=EA=B2=B0=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 --- .../V1/Receiving/StoreReceivingRequest.php | 1 + .../V1/Receiving/UpdateReceivingRequest.php | 1 + app/Models/Tenants/Receiving.php | 10 ++++++ app/Services/ReceivingService.php | 14 +++++++-- ...ertificate_file_id_to_receivings_table.php | 31 +++++++++++++++++++ 5 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 database/migrations/2026_03_11_100000_add_certificate_file_id_to_receivings_table.php diff --git a/app/Http/Requests/V1/Receiving/StoreReceivingRequest.php b/app/Http/Requests/V1/Receiving/StoreReceivingRequest.php index 56904de..8b94a5f 100644 --- a/app/Http/Requests/V1/Receiving/StoreReceivingRequest.php +++ b/app/Http/Requests/V1/Receiving/StoreReceivingRequest.php @@ -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'], ]; } diff --git a/app/Http/Requests/V1/Receiving/UpdateReceivingRequest.php b/app/Http/Requests/V1/Receiving/UpdateReceivingRequest.php index 4273062..b418e2f 100644 --- a/app/Http/Requests/V1/Receiving/UpdateReceivingRequest.php +++ b/app/Http/Requests/V1/Receiving/UpdateReceivingRequest.php @@ -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'], ]; } diff --git a/app/Models/Tenants/Receiving.php b/app/Models/Tenants/Receiving.php index d5799e4..68cedf5 100644 --- a/app/Models/Tenants/Receiving.php +++ b/app/Models/Tenants/Receiving.php @@ -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'); + } + /** * 생성자 관계 */ diff --git a/app/Services/ReceivingService.php b/app/Services/ReceivingService.php index 6ecf6ff..2b2c78c 100644 --- a/app/Services/ReceivingService.php +++ b/app/Services/ReceivingService.php @@ -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); diff --git a/database/migrations/2026_03_11_100000_add_certificate_file_id_to_receivings_table.php b/database/migrations/2026_03_11_100000_add_certificate_file_id_to_receivings_table.php new file mode 100644 index 0000000..719942b --- /dev/null +++ b/database/migrations/2026_03_11_100000_add_certificate_file_id_to_receivings_table.php @@ -0,0 +1,31 @@ +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'); + }); + } +};