feat: add ProductVariant model and service layer for CRUD operations with attachment handling
This commit is contained in:
@@ -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',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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' => [],
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user