diff --git a/database/factories/ProductFactory.php b/database/factories/ProductFactory.php index e5f224c..8d7d1b9 100644 --- a/database/factories/ProductFactory.php +++ b/database/factories/ProductFactory.php @@ -20,7 +20,7 @@ class ProductFactory extends Factory 'sku' => strtoupper($this->faker->bothify('??-####')), 'type' => 'simple', 'status' => 'published', - 'visible' => true, + 'is_visible' => true, 'featured' => false, 'price' => $this->faker->randomFloat(2, 10, 1000), 'regular_price' => $this->faker->randomFloat(2, 10, 1000), diff --git a/database/migrations/create_blax_shop_tables.php.stub b/database/migrations/create_blax_shop_tables.php.stub index 6274c3d..317b49b 100644 --- a/database/migrations/create_blax_shop_tables.php.stub +++ b/database/migrations/create_blax_shop_tables.php.stub @@ -15,7 +15,7 @@ return new class extends Migration if (!Schema::hasTable(config('shop.tables.products', 'products'))) { Schema::create(config('shop.tables.products', 'products'), function (Blueprint $table) { $table->uuid('id')->primary(); - $table->string('name'); + $table->string('name')->nullable(); $table->string('slug')->unique(); $table->string('sku')->nullable()->unique(); $table->text('short_description')->nullable(); @@ -40,7 +40,7 @@ return new class extends Migration $table->boolean('downloadable')->default(false); $table->uuid('parent_id')->nullable(); $table->boolean('featured')->default(false); - $table->boolean('visible')->default(true); + $table->boolean('is_visible')->default(true); $table->string('status')->default('draft'); // draft, published, archived $table->timestamp('published_at')->nullable(); $table->integer('sort_order')->default(0); @@ -50,7 +50,7 @@ return new class extends Migration $table->softDeletes(); $table->index(['slug', 'status']); - $table->index(['featured', 'visible', 'status']); + $table->index(['featured', 'is_visible', 'status']); $table->index('parent_id'); $table->foreign('parent_id')->references('id')->on(config('shop.tables.products', 'products'))->onDelete('cascade'); }); @@ -87,13 +87,13 @@ return new class extends Migration $table->text('description')->nullable(); $table->uuid('parent_id')->nullable(); $table->integer('sort_order')->default(0); - $table->boolean('visible')->default(true); + $table->boolean('is_visible')->default(true); $table->json('meta')->nullable(); $table->timestamps(); $table->softDeletes(); - $table->index(['parent_id', 'visible']); - $table->index(['slug', 'visible']); + $table->index(['parent_id', 'is_visible']); + $table->index(['slug', 'is_visible']); $table->foreign('parent_id')->references('id')->on(config('shop.tables.product_categories', 'product_categories'))->onDelete('cascade'); }); } diff --git a/docs/01-products.md b/docs/01-products.md index 9c20c72..d28cd62 100644 --- a/docs/01-products.md +++ b/docs/01-products.md @@ -30,7 +30,7 @@ $product = Product::create([ 'price' => 49.99, 'regular_price' => 49.99, 'status' => 'published', - 'visible' => true, + 'is_visible' => true, 'featured' => false, ]); @@ -49,7 +49,7 @@ $product = Product::create([ 'sku' => 'HEAD-PREM-001', 'type' => 'simple', 'status' => 'published', - 'visible' => true, + 'is_visible' => true, 'featured' => true, 'published_at' => now(), 'sort_order' => 10, diff --git a/src/Console/Commands/ShopAddExampleProducts.php b/src/Console/Commands/ShopAddExampleProducts.php index e1439d8..e54d98d 100644 --- a/src/Console/Commands/ShopAddExampleProducts.php +++ b/src/Console/Commands/ShopAddExampleProducts.php @@ -107,7 +107,7 @@ class ShopAddExampleProducts extends Command [ 'name' => $name, 'description' => $description, - 'visible' => true, + 'is_visible' => true, 'sort_order' => 0, 'meta' => json_encode((object)[]), ] @@ -131,7 +131,7 @@ class ShopAddExampleProducts extends Command 'sku' => 'EX-' . strtoupper($this->faker->bothify('??-####')), 'type' => $type, 'status' => $this->faker->randomElement(['published', 'published', 'published', 'draft']), // mostly published - 'visible' => true, + 'is_visible' => true, 'featured' => $this->faker->boolean(20), // 20% featured 'price' => $onSale ? $regularPrice * 0.8 : $regularPrice, 'regular_price' => $regularPrice, @@ -353,12 +353,13 @@ class ShopAddExampleProducts extends Command foreach ($variations as $index => $variation) { $variationProduct = Product::create([ + 'name' => $product->name . ' - ' . $variation, 'slug' => $product->slug . '-' . \Illuminate\Support\Str::slug($variation), 'sku' => $product->sku . '-' . strtoupper(substr($variation, 0, 1)), 'type' => 'simple', 'parent_id' => $product->id, 'status' => 'published', - 'visible' => false, // Variations are not directly visible + 'is_visible' => false, // Variations are not directly visible 'price' => $product->price + ($index * 5), // Slight price increase per size 'regular_price' => $product->regular_price + ($index * 5), 'manage_stock' => true, @@ -373,7 +374,7 @@ class ShopAddExampleProducts extends Command ProductAttribute::create([ 'product_id' => $variationProduct->id, - 'name' => 'Size', + 'key' => 'Size', 'value' => $variation, 'sort_order' => 0, 'meta' => json_encode((object)[]), @@ -387,12 +388,13 @@ class ShopAddExampleProducts extends Command for ($i = 0; $i < $groupSize; $i++) { $childProduct = Product::create([ + 'name' => $product->name . ' Item ' . ($i + 1), 'slug' => $product->slug . '-item-' . ($i + 1), 'sku' => $product->sku . '-' . ($i + 1), 'type' => 'simple', 'parent_id' => $product->id, 'status' => 'published', - 'visible' => false, + 'is_visible' => false, 'price' => $this->faker->randomFloat(2, 10, 100), 'manage_stock' => true, 'stock_quantity' => $this->faker->numberBetween(10, 50), diff --git a/src/Models/Product.php b/src/Models/Product.php index 0e5e3e3..5845823 100644 --- a/src/Models/Product.php +++ b/src/Models/Product.php @@ -43,7 +43,7 @@ class Product extends Model implements Purchasable 'downloadable', 'parent_id', 'featured', - 'visible', + 'is_visible', 'status', 'published_at', 'meta', @@ -62,7 +62,7 @@ class Product extends Model implements Purchasable 'sale_end' => 'datetime', 'published_at' => 'datetime', 'featured' => 'boolean', - 'visible' => 'boolean', + 'is_visible' => 'boolean', 'low_stock_threshold' => 'integer', 'sort_order' => 'integer', ]; @@ -348,7 +348,7 @@ class Product extends Model implements Purchasable public function scopeVisible($query) { - return $query->where('visible', true) + return $query->where('is_visible', true) ->where('status', 'published') ->where(function ($q) { $q->whereNull('published_at') @@ -405,7 +405,7 @@ class Product extends Model implements Purchasable public function isVisible(): bool { - if (!$this->visible || $this->status !== 'published') { + if (!$this->is_visible || $this->status !== 'published') { return false; } diff --git a/src/Models/ProductCategory.php b/src/Models/ProductCategory.php index e58ac27..acd6f86 100644 --- a/src/Models/ProductCategory.php +++ b/src/Models/ProductCategory.php @@ -20,12 +20,12 @@ class ProductCategory extends Model 'description', 'parent_id', 'sort_order', - 'visible', + 'is_visible', 'meta', ]; protected $casts = [ - 'visible' => 'boolean', + 'is_visible' => 'boolean', 'meta' => 'object', ]; @@ -82,7 +82,7 @@ class ProductCategory extends Model public function children(): HasMany { return $this->hasMany(self::class, 'parent_id') - ->where('visible', true) + ->where('is_visible', true) ->orderBy('sort_order'); } @@ -94,7 +94,7 @@ class ProductCategory extends Model public function scopeVisible($query) { - return $query->where('visible', true); + return $query->where('is_visible', true); } public function scopeRoots($query) @@ -105,7 +105,7 @@ class ProductCategory extends Model // Backward compatibility accessor public function getIsVisibleAttribute(): bool { - return $this->attributes['visible'] ?? true; + return $this->attributes['is_visible'] ?? true; } public function getProductCountAttribute(): int diff --git a/tests/Feature/ProductCategoryTest.php b/tests/Feature/ProductCategoryTest.php index 0d34a1d..93eb1ab 100644 --- a/tests/Feature/ProductCategoryTest.php +++ b/tests/Feature/ProductCategoryTest.php @@ -92,11 +92,11 @@ class ProductCategoryTest extends TestCase public function it_can_check_visibility() { $visibleCategory = ProductCategory::factory()->create([ - 'visible' => true, + 'is_visible' => true, ]); $hiddenCategory = ProductCategory::factory()->create([ - 'visible' => false, + 'is_visible' => false, ]); $this->assertTrue($visibleCategory->is_visible); diff --git a/tests/Feature/ProductManagementTest.php b/tests/Feature/ProductManagementTest.php index eb16e68..5bdd0ef 100644 --- a/tests/Feature/ProductManagementTest.php +++ b/tests/Feature/ProductManagementTest.php @@ -275,12 +275,12 @@ class ProductManagementTest extends TestCase public function it_can_scope_visible_products() { Product::factory()->create([ - 'visible' => true, + 'is_visible' => true, 'status' => 'published', ]); Product::factory()->create([ - 'visible' => false, + 'is_visible' => false, 'status' => 'published', ]);