Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
02816fb9e7 | ||
|
|
910ce0205d |
@@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file.
|
|||||||
|
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
||||||
|
|
||||||
|
## [0.17.4] - 2026-09-15
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- `boboko:catalog:backfill-skus` — one-off Artisan command to generate a SKU
|
||||||
|
(`SKU-P{product_id}-V{variant_id}`) for every `Lunar\Models\ProductVariant` left with a `null`
|
||||||
|
SKU by the earlier Shopify import (the source export's `Variant SKU` column was genuinely blank
|
||||||
|
for these rows, not an importer mapping bug — see `Modules\MigrateImport\Shopify\
|
||||||
|
ShopifyExportImporter`). Only touches variants missing a SKU; `--dry-run` lists what would
|
||||||
|
change without writing.
|
||||||
|
|
||||||
## [0.17.3] - 2026-09-15
|
## [0.17.3] - 2026-09-15
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
"name": "boboko/core",
|
"name": "boboko/core",
|
||||||
"description": "Core module — authentication and shared panel behaviour",
|
"description": "Core module — authentication and shared panel behaviour",
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"version": "0.17.3",
|
"version": "0.17.4",
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
"Modules\\Core\\": "src/"
|
"Modules\\Core\\": "src/"
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modules\Core\Command;
|
||||||
|
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Lunar\Models\ProductVariant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
class BackfillMissingSkusCommand extends Command
|
||||||
|
{
|
||||||
|
protected $signature = 'boboko:catalog:backfill-skus {--dry-run : List what would change without writing}';
|
||||||
|
|
||||||
|
protected $description = 'Generate a SKU for every product variant that is missing one';
|
||||||
|
|
||||||
|
public function handle(): void
|
||||||
|
{
|
||||||
|
$dryRun = (bool) $this->option('dry-run');
|
||||||
|
|
||||||
|
$query = ProductVariant::query()->whereNull('sku');
|
||||||
|
$total = $query->count();
|
||||||
|
|
||||||
|
if ($total === 0) {
|
||||||
|
$this->info('No variants are missing a SKU.');
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->info(($dryRun ? '[dry-run] ' : '') . "Backfilling SKUs for {$total} variant(s)...");
|
||||||
|
|
||||||
|
$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();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$bar->finish();
|
||||||
|
$this->newLine();
|
||||||
|
$this->info($dryRun ? 'Dry run complete — no changes were written.' : 'Done.');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ namespace Modules\Core\Providers;
|
|||||||
use Illuminate\Support\Facades\Blade;
|
use Illuminate\Support\Facades\Blade;
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
use Modules\Core\Command\AnonymizeCommand;
|
use Modules\Core\Command\AnonymizeCommand;
|
||||||
|
use Modules\Core\Command\BackfillMissingSkusCommand;
|
||||||
use Modules\Core\Command\ExportCleanupCommand;
|
use Modules\Core\Command\ExportCleanupCommand;
|
||||||
use Modules\Core\Command\ExportCommand;
|
use Modules\Core\Command\ExportCommand;
|
||||||
use Modules\Core\Command\ImportCommand;
|
use Modules\Core\Command\ImportCommand;
|
||||||
@@ -36,7 +37,7 @@ class CoreServiceProvider extends ServiceProvider
|
|||||||
], 'core-assets');
|
], 'core-assets');
|
||||||
|
|
||||||
if ($this->app->runningInConsole()) {
|
if ($this->app->runningInConsole()) {
|
||||||
$this->commands([AnonymizeCommand::class, ExportCommand::class, ExportCleanupCommand::class, ImportCommand::class, MigrateImportCommand::class, TuneProductSearchCommand::class]);
|
$this->commands([AnonymizeCommand::class, ExportCommand::class, ExportCleanupCommand::class, ImportCommand::class, MigrateImportCommand::class, TuneProductSearchCommand::class, BackfillMissingSkusCommand::class]);
|
||||||
|
|
||||||
//Overriding lunar:install
|
//Overriding lunar:install
|
||||||
$this->app->booted(fn () => $this->commands([InstallLunarCommand::class]));
|
$this->app->booted(fn () => $this->commands([InstallLunarCommand::class]));
|
||||||
|
|||||||
Reference in New Issue
Block a user