feat: add ProductVariant model and service layer for CRUD operations with attachment handling

This commit is contained in:
2026-07-01 10:09:04 -03:00
parent d6a17cb449
commit a0a0cc7255
4 changed files with 18 additions and 18 deletions

View File

@@ -13,7 +13,7 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
#[Fillable([ #[Fillable([
'producto_id', 'producto_id',
'stock', 'stock',
'is_default', 'is_placeholder',
])] ])]
class ProductVariant extends Model class ProductVariant extends Model
{ {
@@ -26,7 +26,7 @@ class ProductVariant extends Model
return [ return [
'producto_id' => 'integer', 'producto_id' => 'integer',
'stock' => 'integer', 'stock' => 'integer',
'is_default' => 'boolean', 'is_placeholder' => 'boolean',
]; ];
} }

View File

@@ -44,7 +44,7 @@ class ProductService
// Create default variant with stock // Create default variant with stock
$this->createVariant($product, [ $this->createVariant($product, [
'stock' => $stock, 'stock' => $stock,
'is_default' => true, 'is_placeholder' => true,
'definitions' => [], 'definitions' => [],
]); ]);
@@ -117,14 +117,14 @@ class ProductService
$images = $data['images'] ?? []; $images = $data['images'] ?? [];
unset($data['images']); unset($data['images']);
// Determine if the variant being created is a default one // Determine if the variant being created is a placeholder one
$hasDefinitions = ! empty($data['definitions']); $hasDefinitions = ! empty($data['definitions']);
$isDefault = $data['is_default'] ?? (! $hasDefinitions); $isPlaceholder = $data['is_placeholder'] ?? (! $hasDefinitions);
$data['is_default'] = $isDefault; $data['is_placeholder'] = $isPlaceholder;
// If the variant being created is not a default variant, remove any existing default variants // If the variant being created is not a placeholder variant, remove any existing placeholder variants
if (! $isDefault) { if (! $isPlaceholder) {
$defaultVariants = $product->variants()->where('is_default', true)->get(); $defaultVariants = $product->variants()->where('is_placeholder', true)->get();
foreach ($defaultVariants as $defaultVariant) { foreach ($defaultVariants as $defaultVariant) {
$this->deleteVariantAttachments($defaultVariant); $this->deleteVariantAttachments($defaultVariant);
$product->deleteVariant($defaultVariant); $product->deleteVariant($defaultVariant);
@@ -180,7 +180,7 @@ class ProductService
if ($product->variants()->count() === 0) { if ($product->variants()->count() === 0) {
$product->createVariant([ $product->createVariant([
'stock' => 0, 'stock' => 0,
'is_default' => true, 'is_placeholder' => true,
'definitions' => [], 'definitions' => [],
]); ]);
} }

View File

@@ -12,7 +12,7 @@ return new class extends Migration
public function up(): void public function up(): void
{ {
Schema::table('productos_variantes', function (Blueprint $table) { Schema::table('productos_variantes', function (Blueprint $table) {
$table->boolean('is_default')->default(false)->after('stock'); $table->boolean('is_placeholder')->default(false)->after('stock');
}); });
} }
@@ -22,7 +22,7 @@ return new class extends Migration
public function down(): void public function down(): void
{ {
Schema::table('productos_variantes', function (Blueprint $table) { Schema::table('productos_variantes', function (Blueprint $table) {
$table->dropColumn('is_default'); $table->dropColumn('is_placeholder');
}); });
} }
}; };

View File

@@ -635,7 +635,7 @@ class ProductControllerTest extends TestCase
$variant = $product->variants()->first(); $variant = $product->variants()->first();
$this->assertEquals(15, $variant->stock); $this->assertEquals(15, $variant->stock);
$this->assertTrue($variant->is_default); $this->assertTrue($variant->is_placeholder);
// Should have no definitions // Should have no definitions
$this->assertEquals(0, $variant->definitions()->count()); $this->assertEquals(0, $variant->definitions()->count());
} }
@@ -654,7 +654,7 @@ class ProductControllerTest extends TestCase
$defaultVariant = $product->variants()->create([ $defaultVariant = $product->variants()->create([
'stock' => 10, 'stock' => 10,
'is_default' => true, 'is_placeholder' => true,
]); ]);
$this->assertEquals(1, $product->variants()->count()); $this->assertEquals(1, $product->variants()->count());
@@ -682,7 +682,7 @@ class ProductControllerTest extends TestCase
$this->assertEquals(1, $product->variants()->count()); $this->assertEquals(1, $product->variants()->count());
$newVariant = $product->variants()->first(); $newVariant = $product->variants()->first();
$this->assertEquals(5, $newVariant->stock); $this->assertEquals(5, $newVariant->stock);
$this->assertFalse($newVariant->is_default); $this->assertFalse($newVariant->is_placeholder);
} }
public function test_it_restores_default_variant_when_all_variants_are_deleted(): void public function test_it_restores_default_variant_when_all_variants_are_deleted(): void
@@ -699,7 +699,7 @@ class ProductControllerTest extends TestCase
$realVariant = $product->createVariant([ $realVariant = $product->createVariant([
'stock' => 5, 'stock' => 5,
'is_default' => false, 'is_placeholder' => false,
'definitions' => [ 'definitions' => [
[ [
'products_attribute_id' => $productAttributes['size']->id, 'products_attribute_id' => $productAttributes['size']->id,
@@ -714,11 +714,11 @@ class ProductControllerTest extends TestCase
$response = $this->deleteJson("/api/tenants/{$this->tenant->codigo}/productos/{$product->id}/variants/{$realVariant->id}"); $response = $this->deleteJson("/api/tenants/{$this->tenant->codigo}/productos/{$product->id}/variants/{$realVariant->id}");
$response->assertNoContent(); $response->assertNoContent();
// A default variant should be recreated with stock 0 and is_default = true // A default variant should be recreated with stock 0 and is_placeholder = true
$this->assertEquals(1, $product->variants()->count()); $this->assertEquals(1, $product->variants()->count());
$defaultVariant = $product->variants()->first(); $defaultVariant = $product->variants()->first();
$this->assertEquals(0, $defaultVariant->stock); $this->assertEquals(0, $defaultVariant->stock);
$this->assertTrue($defaultVariant->is_default); $this->assertTrue($defaultVariant->is_placeholder);
$this->assertEquals(0, $defaultVariant->definitions()->count()); $this->assertEquals(0, $defaultVariant->definitions()->count());
} }