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; } }