From 37b49963f63a0de0402074e74c5a893b12488ede Mon Sep 17 00:00:00 2001 From: Konstantinos Arvanitakis Date: Tue, 22 Sep 2026 14:55:18 +0300 Subject: [PATCH] Feat: Adding Backfill Skus to the Migrate Import Job --- src/Catalog/Services/SkuBackfillService.php | 56 +++++++++++++++++++++ src/Command/BackfillMissingSkusCommand.php | 35 +++++-------- src/MigrateImport/RunMigrateImportJob.php | 13 ++++- 3 files changed, 81 insertions(+), 23 deletions(-) create mode 100644 src/Catalog/Services/SkuBackfillService.php diff --git a/src/Catalog/Services/SkuBackfillService.php b/src/Catalog/Services/SkuBackfillService.php new file mode 100644 index 0000000..ab7fdd9 --- /dev/null +++ b/src/Catalog/Services/SkuBackfillService.php @@ -0,0 +1,56 @@ +whereNull('sku'); + $total = $query->count(); + + if ($total === 0) { + return 0; + } + + $query->chunkById(500, function ($variants) use ($dryRun, $onEach) { + foreach ($variants as $variant) { + $sku = "SKU-P{$variant->product_id}-V{$variant->id}"; + + if (! $dryRun) { + $variant->update(['sku' => $sku]); + } + + if ($onEach !== null) { + $onEach($variant, $sku); + } + } + }); + + return $total; + } +} diff --git a/src/Command/BackfillMissingSkusCommand.php b/src/Command/BackfillMissingSkusCommand.php index 6bbbbed..0998d63 100644 --- a/src/Command/BackfillMissingSkusCommand.php +++ b/src/Command/BackfillMissingSkusCommand.php @@ -4,15 +4,13 @@ namespace Modules\Core\Command; use Illuminate\Console\Command; use Lunar\Models\ProductVariant; +use Modules\Core\Catalog\Services\SkuBackfillService; /** - * One-off backfill for variants the Shopify import left with a blank SKU — - * not an importer bug, the source CSV rows genuinely had no `Variant SKU` - * value (see Modules\MigrateImport\Shopify\ShopifyExportImporter) — so - * this synthesizes one instead of re-running the import. Format is - * "SKU-P{product_id}-V{variant_id}": deterministic and guaranteed unique - * without a uniqueness check, since product_id/variant_id already are. - * Only variants with a null `sku` are touched. + * CLI wrapper (--dry-run, a progress bar) around Catalog\Services\ + * SkuBackfillService — see that class's own docblock for the actual + * backfill logic, also called automatically after a Shopify import (see + * MigrateImport\RunMigrateImportJob). */ class BackfillMissingSkusCommand extends Command { @@ -20,12 +18,11 @@ class BackfillMissingSkusCommand extends Command protected $description = 'Generate a SKU for every product variant that is missing one'; - public function handle(): void + public function handle(SkuBackfillService $backfill): void { $dryRun = (bool) $this->option('dry-run'); - $query = ProductVariant::query()->whereNull('sku'); - $total = $query->count(); + $total = ProductVariant::query()->whereNull('sku')->count(); if ($total === 0) { $this->info('No variants are missing a SKU.'); @@ -38,19 +35,13 @@ class BackfillMissingSkusCommand extends Command $bar = $this->output->createProgressBar($total); $bar->start(); - $query->chunkById(500, function ($variants) use ($dryRun, $bar) { - foreach ($variants as $variant) { - $sku = "SKU-P{$variant->product_id}-V{$variant->id}"; - - if ($dryRun) { - $this->newLine(); - $this->line("Variant {$variant->id}: sku => {$sku}"); - } else { - $variant->update(['sku' => $sku]); - } - - $bar->advance(); + $backfill->backfill($dryRun, function (ProductVariant $variant, string $sku) use ($dryRun, $bar) { + if ($dryRun) { + $this->newLine(); + $this->line("Variant {$variant->id}: sku => {$sku}"); } + + $bar->advance(); }); $bar->finish(); diff --git a/src/MigrateImport/RunMigrateImportJob.php b/src/MigrateImport/RunMigrateImportJob.php index 16dfb4d..e43123b 100644 --- a/src/MigrateImport/RunMigrateImportJob.php +++ b/src/MigrateImport/RunMigrateImportJob.php @@ -7,6 +7,7 @@ use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; +use Modules\Core\Catalog\Services\SkuBackfillService; class RunMigrateImportJob implements ShouldQueue { @@ -20,9 +21,19 @@ class RunMigrateImportJob implements ShouldQueue ) { } - public function handle(): void + public function handle(SkuBackfillService $skuBackfill): void { $importer = ImporterFactory::make($this->spec); $importer->import($this->spec); + + // Only Shopify's importer creates ProductVariant rows at all (see + // Shopify\ShopifyExportImporter) — JudgeMe never touches products, + // so running this for that source would just be a guaranteed + // no-op query every time. Source CSV rows genuinely can have no + // `Variant SKU` value; see SkuBackfillService's own docblock for + // why that's synthesized rather than treated as an importer bug. + if ($this->spec->source === 'shopify') { + $skuBackfill->backfill(); + } } }