Files
sam-api/app/Console/Commands/BackfillQuoteProductCodeCommand.php
권혁성 e6c02292d2 feat: [quote/quality] Phase 2B 견적 product_code 자동추출 + inspections work_order_id FK
- QuoteService: extractProductCodeFromInputs() 추가, store/update에서 자동 추출
- BackfillQuoteProductCodeCommand: 기존 quotes 25건 product_code 보정
- inspections 테이블에 work_order_id FK 마이그레이션 (nullable, nullOnDelete)
- Inspection↔WorkOrder 양방향 관계 추가
- InspectionService: store/show/index에 work_order_id 처리 + transformToFrontend
- InspectionStoreRequest: work_order_id 검증 규칙 추가
2026-02-27 23:18:09 +09:00

55 lines
1.6 KiB
PHP

<?php
namespace App\Console\Commands;
use App\Models\Quote\Quote;
use Illuminate\Console\Command;
class BackfillQuoteProductCodeCommand extends Command
{
protected $signature = 'data:backfill-quote-product-code {--dry-run : 실제 저장하지 않고 결과만 출력}';
protected $description = 'quotes.product_code가 비어있는 레코드에 calculation_inputs.items[0].productCode 값 보정';
public function handle(): int
{
$dryRun = $this->option('dry-run');
$quotes = Quote::whereNull('product_code')
->whereNotNull('calculation_inputs')
->get();
$this->info("대상: {$quotes->count()}".($dryRun ? ' (dry-run)' : ''));
$updated = 0;
$skipped = 0;
foreach ($quotes as $quote) {
$inputs = $quote->calculation_inputs;
if (! is_array($inputs)) {
$inputs = json_decode($inputs, true);
}
$productCode = $inputs['items'][0]['productCode'] ?? null;
if (! $productCode) {
$skipped++;
$this->line(" SKIP #{$quote->id} ({$quote->quote_number}) — productCode 없음");
continue;
}
if (! $dryRun) {
$quote->update(['product_code' => $productCode]);
}
$updated++;
$this->line(' '.($dryRun ? 'WOULD ' : '')."UPDATE #{$quote->id} ({$quote->quote_number}) → {$productCode}");
}
$this->info("완료: 보정 {$updated}건, 스킵 {$skipped}");
return self::SUCCESS;
}
}