feat(catalog): add group_order field to catalog items and update related logic
This commit is contained in:
@@ -27,6 +27,7 @@ use Illuminate\Support\Collection;
|
|||||||
'type',
|
'type',
|
||||||
'slug',
|
'slug',
|
||||||
'nombre',
|
'nombre',
|
||||||
|
'group_order',
|
||||||
'descripcion',
|
'descripcion',
|
||||||
'precio',
|
'precio',
|
||||||
'inventory_policy',
|
'inventory_policy',
|
||||||
@@ -47,6 +48,7 @@ class CatalogItem extends Model
|
|||||||
'inventory_policy' => InventoryPolicy::Tracked->value,
|
'inventory_policy' => InventoryPolicy::Tracked->value,
|
||||||
'inventory_subject' => InventorySubject::Product->value,
|
'inventory_subject' => InventorySubject::Product->value,
|
||||||
'has_tickets' => false,
|
'has_tickets' => false,
|
||||||
|
'group_order' => 0,
|
||||||
];
|
];
|
||||||
|
|
||||||
protected function casts(): array
|
protected function casts(): array
|
||||||
@@ -56,6 +58,7 @@ class CatalogItem extends Model
|
|||||||
'brand_id' => 'integer',
|
'brand_id' => 'integer',
|
||||||
'inventory_id' => 'integer',
|
'inventory_id' => 'integer',
|
||||||
'type' => CatalogItemType::class,
|
'type' => CatalogItemType::class,
|
||||||
|
'group_order' => 'integer',
|
||||||
'precio' => 'decimal:2',
|
'precio' => 'decimal:2',
|
||||||
'inventory_policy' => InventoryPolicy::class,
|
'inventory_policy' => InventoryPolicy::class,
|
||||||
'inventory_subject' => InventorySubject::class,
|
'inventory_subject' => InventorySubject::class,
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ class StoreCatalogItemRequest extends FormRequest
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
'nombre' => ['required', 'string', 'max:255'],
|
'nombre' => ['required', 'string', 'max:255'],
|
||||||
|
'group_order' => ['sometimes', 'integer', 'min:0'],
|
||||||
'descripcion' => ['sometimes', 'nullable', 'string'],
|
'descripcion' => ['sometimes', 'nullable', 'string'],
|
||||||
'precio' => ['required', 'numeric', 'min:0'],
|
'precio' => ['required', 'numeric', 'min:0'],
|
||||||
'inventory_policy' => [Rule::prohibitedIf($isBundle), 'sometimes', Rule::enum(InventoryPolicy::class)],
|
'inventory_policy' => [Rule::prohibitedIf($isBundle), 'sometimes', Rule::enum(InventoryPolicy::class)],
|
||||||
|
|||||||
@@ -72,7 +72,9 @@ class FeaturedGroupService
|
|||||||
FeaturedGroupSource::Category => $query
|
FeaturedGroupSource::Category => $query
|
||||||
->where('catalog_items.category_id', $featuredGroup->category_id)
|
->where('catalog_items.category_id', $featuredGroup->category_id)
|
||||||
->orderBy('catalog_items.id'),
|
->orderBy('catalog_items.id'),
|
||||||
FeaturedGroupSource::All => $query->orderBy('catalog_items.id'),
|
FeaturedGroupSource::All => $query
|
||||||
|
->orderBy('catalog_items.group_order')
|
||||||
|
->orderBy('catalog_items.id'),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('catalog_items', function (Blueprint $table): void {
|
||||||
|
$table->unsignedInteger('group_order')->default(0)->after('nombre');
|
||||||
|
});
|
||||||
|
|
||||||
|
$footballOrder = [
|
||||||
|
1 => [
|
||||||
|
'slugs' => ['camiseta', 'camiseta-oficial-fnfi'],
|
||||||
|
'names' => ['Camiseta', 'CAMISETA OFICIAL FNFI'],
|
||||||
|
],
|
||||||
|
2 => [
|
||||||
|
'slugs' => ['alojamiento', 'camping'],
|
||||||
|
'names' => ['Alojamiento', 'CAMPING'],
|
||||||
|
],
|
||||||
|
3 => [
|
||||||
|
'slugs' => ['abono'],
|
||||||
|
'names' => ['Abono', 'ABONO'],
|
||||||
|
],
|
||||||
|
4 => [
|
||||||
|
'slugs' => ['comida'],
|
||||||
|
'names' => ['Comida', 'COMIDA'],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($footballOrder as $order => $identifiers) {
|
||||||
|
DB::table('catalog_items')
|
||||||
|
->where('tenant_code', 'fiesta_futbol_infantil')
|
||||||
|
->where(function ($query) use ($identifiers): void {
|
||||||
|
$query
|
||||||
|
->whereIn('slug', $identifiers['slugs'])
|
||||||
|
->orWhereIn('nombre', $identifiers['names']);
|
||||||
|
})
|
||||||
|
->update(['group_order' => $order]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('catalog_items', function (Blueprint $table): void {
|
||||||
|
$table->dropColumn('group_order');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -78,6 +78,7 @@ class FiestaFutbolInfantilProductSeeder extends Seeder
|
|||||||
$this->createProduct($tenant, [
|
$this->createProduct($tenant, [
|
||||||
'slug' => 'camiseta',
|
'slug' => 'camiseta',
|
||||||
'nombre' => 'Camiseta',
|
'nombre' => 'Camiseta',
|
||||||
|
'group_order' => 1,
|
||||||
'category_id' => $categories['merchandising']->id,
|
'category_id' => $categories['merchandising']->id,
|
||||||
'precio' => 18000,
|
'precio' => 18000,
|
||||||
'attribute_codes' => ['color', 'talle'],
|
'attribute_codes' => ['color', 'talle'],
|
||||||
@@ -92,6 +93,7 @@ class FiestaFutbolInfantilProductSeeder extends Seeder
|
|||||||
$this->createProduct($tenant, [
|
$this->createProduct($tenant, [
|
||||||
'slug' => 'alojamiento',
|
'slug' => 'alojamiento',
|
||||||
'nombre' => 'Alojamiento',
|
'nombre' => 'Alojamiento',
|
||||||
|
'group_order' => 2,
|
||||||
'category_id' => $categories['alojamientos']->id,
|
'category_id' => $categories['alojamientos']->id,
|
||||||
'precio' => 35000,
|
'precio' => 35000,
|
||||||
'attribute_codes' => ['tipo_alojamiento'],
|
'attribute_codes' => ['tipo_alojamiento'],
|
||||||
@@ -104,6 +106,7 @@ class FiestaFutbolInfantilProductSeeder extends Seeder
|
|||||||
$this->createProduct($tenant, [
|
$this->createProduct($tenant, [
|
||||||
'slug' => 'comida',
|
'slug' => 'comida',
|
||||||
'nombre' => 'Comida',
|
'nombre' => 'Comida',
|
||||||
|
'group_order' => 4,
|
||||||
'category_id' => $categories['comidas']->id,
|
'category_id' => $categories['comidas']->id,
|
||||||
'precio' => 4000,
|
'precio' => 4000,
|
||||||
'attribute_codes' => ['event_date', 'horario', 'servicio'],
|
'attribute_codes' => ['event_date', 'horario', 'servicio'],
|
||||||
@@ -126,6 +129,7 @@ class FiestaFutbolInfantilProductSeeder extends Seeder
|
|||||||
$this->createProduct($tenant, [
|
$this->createProduct($tenant, [
|
||||||
'slug' => 'abono',
|
'slug' => 'abono',
|
||||||
'nombre' => 'Abono',
|
'nombre' => 'Abono',
|
||||||
|
'group_order' => 3,
|
||||||
'category_id' => $categories['entradas']->id,
|
'category_id' => $categories['entradas']->id,
|
||||||
'precio' => 40000,
|
'precio' => 40000,
|
||||||
'has_tickets' => true,
|
'has_tickets' => true,
|
||||||
|
|||||||
@@ -354,8 +354,10 @@ class CatalogControllerTest extends TestCase
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
$food = $this->createItem($tenant, 'Hamburger');
|
$food = $this->createItem($tenant, 'Hamburger');
|
||||||
|
$food->update(['group_order' => 2]);
|
||||||
$food->category()->associate($category)->save();
|
$food->category()->associate($category)->save();
|
||||||
$this->createItem($tenant, 'Parking');
|
$parking = $this->createItem($tenant, 'Parking');
|
||||||
|
$parking->update(['group_order' => 1]);
|
||||||
|
|
||||||
$this->getJson("/api/tenants/{$tenant->codigo}/catalog")
|
$this->getJson("/api/tenants/{$tenant->codigo}/catalog")
|
||||||
->assertOk()
|
->assertOk()
|
||||||
@@ -364,6 +366,9 @@ class CatalogControllerTest extends TestCase
|
|||||||
->assertJsonPath('0.items.0.nombre', 'Hamburger')
|
->assertJsonPath('0.items.0.nombre', 'Hamburger')
|
||||||
->assertJsonPath('1.title', 'All products')
|
->assertJsonPath('1.title', 'All products')
|
||||||
->assertJsonCount(2, '1.items.data')
|
->assertJsonCount(2, '1.items.data')
|
||||||
|
->assertJsonPath('1.items.data.0.nombre', 'Parking')
|
||||||
|
->assertJsonPath('1.items.data.1.nombre', 'Hamburger')
|
||||||
|
->assertJsonMissingPath('1.items.data.0.group_order')
|
||||||
->assertJsonPath('1.items.meta.total', 2);
|
->assertJsonPath('1.items.meta.total', 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ class CatalogItemControllerTest extends TestCase
|
|||||||
$response = $this->postJson("/api/tenants/{$tenant->codigo}/catalog-items", [
|
$response = $this->postJson("/api/tenants/{$tenant->codigo}/catalog-items", [
|
||||||
'slug' => 'shirt',
|
'slug' => 'shirt',
|
||||||
'nombre' => 'Shirt',
|
'nombre' => 'Shirt',
|
||||||
|
'group_order' => 7,
|
||||||
'precio' => 100,
|
'precio' => 100,
|
||||||
'max_units_per_user' => 4,
|
'max_units_per_user' => 4,
|
||||||
'attribute_codes' => [$attribute->codigo],
|
'attribute_codes' => [$attribute->codigo],
|
||||||
@@ -47,6 +48,7 @@ class CatalogItemControllerTest extends TestCase
|
|||||||
$response
|
$response
|
||||||
->assertCreated()
|
->assertCreated()
|
||||||
->assertJsonPath('data.nombre', 'Shirt')
|
->assertJsonPath('data.nombre', 'Shirt')
|
||||||
|
->assertJsonMissingPath('data.group_order')
|
||||||
->assertJsonPath('data.max_units_per_user', 4)
|
->assertJsonPath('data.max_units_per_user', 4)
|
||||||
->assertJsonCount(2, 'data.images')
|
->assertJsonCount(2, 'data.images')
|
||||||
->assertJsonCount(1, 'data.variants')
|
->assertJsonCount(1, 'data.variants')
|
||||||
@@ -57,6 +59,7 @@ class CatalogItemControllerTest extends TestCase
|
|||||||
|
|
||||||
$this->assertSame([0, 1], $item->attachments()->get()->pluck('pivot.orden')->all());
|
$this->assertSame([0, 1], $item->attachments()->get()->pluck('pivot.orden')->all());
|
||||||
$this->assertSame(4, $item->max_units_per_user);
|
$this->assertSame(4, $item->max_units_per_user);
|
||||||
|
$this->assertSame(7, $item->group_order);
|
||||||
$this->assertSame([0], $variant->attachments()->get()->pluck('pivot.orden')->all());
|
$this->assertSame([0], $variant->attachments()->get()->pluck('pivot.orden')->all());
|
||||||
$this->assertDatabaseHas('catalog_items_attachments', [
|
$this->assertDatabaseHas('catalog_items_attachments', [
|
||||||
'catalog_item_id' => $item->id,
|
'catalog_item_id' => $item->id,
|
||||||
|
|||||||
@@ -70,6 +70,14 @@ class FiestaFutbolInfantilProductSeederTest extends TestCase
|
|||||||
['abono', 'alojamiento', 'camiseta', 'comida'],
|
['abono', 'alojamiento', 'camiseta', 'comida'],
|
||||||
CatalogItem::query()->where('tenant_code', $tenant->codigo)->orderBy('slug')->pluck('slug')->all(),
|
CatalogItem::query()->where('tenant_code', $tenant->codigo)->orderBy('slug')->pluck('slug')->all(),
|
||||||
);
|
);
|
||||||
|
$this->assertSame(
|
||||||
|
['camiseta', 'alojamiento', 'abono', 'comida'],
|
||||||
|
CatalogItem::query()
|
||||||
|
->where('tenant_code', $tenant->codigo)
|
||||||
|
->orderBy('group_order')
|
||||||
|
->pluck('slug')
|
||||||
|
->all(),
|
||||||
|
);
|
||||||
$this->assertTrue(
|
$this->assertTrue(
|
||||||
CatalogItem::query()
|
CatalogItem::query()
|
||||||
->where('tenant_code', $tenant->codigo)
|
->where('tenant_code', $tenant->codigo)
|
||||||
|
|||||||
@@ -83,11 +83,13 @@ class CatalogModelsTest extends TestCase
|
|||||||
public function test_catalog_item_is_the_catalog_root(): void
|
public function test_catalog_item_is_the_catalog_root(): void
|
||||||
{
|
{
|
||||||
$item = new CatalogItem;
|
$item = new CatalogItem;
|
||||||
|
$this->assertSame(0, $item->group_order);
|
||||||
$item->setRawAttributes([
|
$item->setRawAttributes([
|
||||||
'category_id' => '10',
|
'category_id' => '10',
|
||||||
'brand_id' => '20',
|
'brand_id' => '20',
|
||||||
'inventory_id' => '30',
|
'inventory_id' => '30',
|
||||||
'type' => CatalogItemType::Standard->value,
|
'type' => CatalogItemType::Standard->value,
|
||||||
|
'group_order' => '4',
|
||||||
'precio' => '12.50',
|
'precio' => '12.50',
|
||||||
'inventory_policy' => InventoryPolicy::Tracked->value,
|
'inventory_policy' => InventoryPolicy::Tracked->value,
|
||||||
'inventory_subject' => InventorySubject::Seat->value,
|
'inventory_subject' => InventorySubject::Seat->value,
|
||||||
@@ -100,6 +102,7 @@ class CatalogModelsTest extends TestCase
|
|||||||
$this->assertSame(20, $item->brand_id);
|
$this->assertSame(20, $item->brand_id);
|
||||||
$this->assertSame(30, $item->inventory_id);
|
$this->assertSame(30, $item->inventory_id);
|
||||||
$this->assertSame(CatalogItemType::Standard, $item->type);
|
$this->assertSame(CatalogItemType::Standard, $item->type);
|
||||||
|
$this->assertSame(4, $item->group_order);
|
||||||
$this->assertSame('12.50', $item->precio);
|
$this->assertSame('12.50', $item->precio);
|
||||||
$this->assertSame(InventoryPolicy::Tracked, $item->inventory_policy);
|
$this->assertSame(InventoryPolicy::Tracked, $item->inventory_policy);
|
||||||
$this->assertSame(InventorySubject::Seat, $item->inventory_subject);
|
$this->assertSame(InventorySubject::Seat, $item->inventory_subject);
|
||||||
|
|||||||
Reference in New Issue
Block a user