feat: implement delete functionality for accommodations, entries, foods, and merchandise; enhance related services and tests
This commit is contained in:
@@ -305,6 +305,39 @@ class CatalogService
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function deleteVariant(Variant $variant): void
|
||||||
|
{
|
||||||
|
DB::transaction(function () use ($variant): void {
|
||||||
|
$variant = Variant::query()
|
||||||
|
->with('attachments')
|
||||||
|
->lockForUpdate()
|
||||||
|
->findOrFail($variant->getKey());
|
||||||
|
$catalogItem = CatalogItem::query()
|
||||||
|
->lockForUpdate()
|
||||||
|
->findOrFail($variant->catalog_item_id);
|
||||||
|
$attachments = $variant->attachments;
|
||||||
|
$inventoryId = $variant->inventory_id;
|
||||||
|
|
||||||
|
$variant->attachments()->detach();
|
||||||
|
$variant->delete();
|
||||||
|
Inventory::query()->whereKey($inventoryId)->delete();
|
||||||
|
|
||||||
|
$minimumPrice = $catalogItem->variants()->min('precio');
|
||||||
|
|
||||||
|
if ($minimumPrice === null) {
|
||||||
|
$this->delete($catalogItem);
|
||||||
|
} else {
|
||||||
|
$catalogItem->update(['precio' => $minimumPrice]);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($attachments as $attachment) {
|
||||||
|
if (! DB::table('catalog_items_attachments')->where('attachment_id', $attachment->id)->exists()) {
|
||||||
|
$this->attachmentService->delete($attachment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private function createInventory(int $realStock): Inventory
|
private function createInventory(int $realStock): Inventory
|
||||||
{
|
{
|
||||||
return Inventory::query()->create([
|
return Inventory::query()->create([
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use App\Domains\FiestaFutbolInfantil\Resources\AccommodationResource;
|
|||||||
use App\Domains\FiestaFutbolInfantil\Services\AccommodationService;
|
use App\Domains\FiestaFutbolInfantil\Services\AccommodationService;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Response;
|
||||||
|
|
||||||
class AccommodationController extends Controller
|
class AccommodationController extends Controller
|
||||||
{
|
{
|
||||||
@@ -30,4 +31,14 @@ class AccommodationController extends Controller
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function destroy(Request $request, int $accommodation): Response
|
||||||
|
{
|
||||||
|
$this->accommodationService->delete(
|
||||||
|
$request->user()->tenant()->firstOrFail(),
|
||||||
|
$accommodation,
|
||||||
|
);
|
||||||
|
|
||||||
|
return response()->noContent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ use App\Http\Controllers\Controller;
|
|||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
|
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
|
||||||
|
use Illuminate\Http\Response;
|
||||||
|
|
||||||
class EntryController extends Controller
|
class EntryController extends Controller
|
||||||
{
|
{
|
||||||
@@ -34,4 +35,14 @@ class EntryController extends Controller
|
|||||||
->response()
|
->response()
|
||||||
->setStatusCode(200);
|
->setStatusCode(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function destroy(Request $request, int $entry): Response
|
||||||
|
{
|
||||||
|
$this->entryService->delete(
|
||||||
|
$request->user()->tenant()->firstOrFail(),
|
||||||
|
$entry,
|
||||||
|
);
|
||||||
|
|
||||||
|
return response()->noContent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use App\Domains\FiestaFutbolInfantil\Resources\FoodResource;
|
|||||||
use App\Domains\FiestaFutbolInfantil\Services\FoodService;
|
use App\Domains\FiestaFutbolInfantil\Services\FoodService;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Response;
|
||||||
|
|
||||||
class FoodController extends Controller
|
class FoodController extends Controller
|
||||||
{
|
{
|
||||||
@@ -30,4 +31,14 @@ class FoodController extends Controller
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function destroy(Request $request, int $food): Response
|
||||||
|
{
|
||||||
|
$this->foodService->delete(
|
||||||
|
$request->user()->tenant()->firstOrFail(),
|
||||||
|
$food,
|
||||||
|
);
|
||||||
|
|
||||||
|
return response()->noContent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ use App\Http\Controllers\Controller;
|
|||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
|
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
|
||||||
|
use Illuminate\Http\Response;
|
||||||
|
|
||||||
class MerchandiseController extends Controller
|
class MerchandiseController extends Controller
|
||||||
{
|
{
|
||||||
@@ -33,4 +34,14 @@ class MerchandiseController extends Controller
|
|||||||
->response()
|
->response()
|
||||||
->setStatusCode(200);
|
->setStatusCode(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function destroy(Request $request, int $merchandise): Response
|
||||||
|
{
|
||||||
|
$this->merchandiseService->delete(
|
||||||
|
$request->user()->tenant()->firstOrFail(),
|
||||||
|
$merchandise,
|
||||||
|
);
|
||||||
|
|
||||||
|
return response()->noContent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ use App\Domains\Catalog\Models\Category;
|
|||||||
use App\Domains\Catalog\Models\Inventory;
|
use App\Domains\Catalog\Models\Inventory;
|
||||||
use App\Domains\Catalog\Models\ItemAttribute;
|
use App\Domains\Catalog\Models\ItemAttribute;
|
||||||
use App\Domains\Catalog\Models\Variant;
|
use App\Domains\Catalog\Models\Variant;
|
||||||
|
use App\Domains\Catalog\Services\CatalogService;
|
||||||
use App\Domains\Tenant\Models\Tenant;
|
use App\Domains\Tenant\Models\Tenant;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
@@ -20,6 +21,8 @@ class AccommodationService
|
|||||||
{
|
{
|
||||||
private const ATTRIBUTE_CODE = 'tipo_alojamiento';
|
private const ATTRIBUTE_CODE = 'tipo_alojamiento';
|
||||||
|
|
||||||
|
public function __construct(private readonly CatalogService $catalogService) {}
|
||||||
|
|
||||||
public function current(Tenant $tenant): ?CatalogItem
|
public function current(Tenant $tenant): ?CatalogItem
|
||||||
{
|
{
|
||||||
return CatalogItem::query()
|
return CatalogItem::query()
|
||||||
@@ -86,6 +89,18 @@ class AccommodationService
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function delete(Tenant $tenant, int $accommodationId): void
|
||||||
|
{
|
||||||
|
$variant = Variant::query()
|
||||||
|
->whereKey($accommodationId)
|
||||||
|
->whereHas('catalogItem', fn ($query) => $query
|
||||||
|
->where('tenant_code', $tenant->codigo)
|
||||||
|
->where('slug', 'alojamiento'))
|
||||||
|
->firstOrFail();
|
||||||
|
|
||||||
|
$this->catalogService->deleteVariant($variant);
|
||||||
|
}
|
||||||
|
|
||||||
private function attribute(Tenant $tenant): Attribute
|
private function attribute(Tenant $tenant): Attribute
|
||||||
{
|
{
|
||||||
$attribute = Attribute::query()
|
$attribute = Attribute::query()
|
||||||
|
|||||||
@@ -76,6 +76,18 @@ class EntryService
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function delete(Tenant $tenant, int $entryId): void
|
||||||
|
{
|
||||||
|
$entry = CatalogItem::query()
|
||||||
|
->whereKey($entryId)
|
||||||
|
->where('tenant_code', $tenant->codigo)
|
||||||
|
->where('event_product_type', EventProductType::Entry->value)
|
||||||
|
->whereHas('category', fn ($query) => $query->where('nombre', 'Entradas'))
|
||||||
|
->firstOrFail();
|
||||||
|
|
||||||
|
$this->catalogService->delete($entry);
|
||||||
|
}
|
||||||
|
|
||||||
/** @param array<string, mixed> $entry */
|
/** @param array<string, mixed> $entry */
|
||||||
private function update(Tenant $tenant, Category $category, array $entry, int $index): CatalogItem
|
private function update(Tenant $tenant, Category $category, array $entry, int $index): CatalogItem
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ use App\Domains\Catalog\Models\Category;
|
|||||||
use App\Domains\Catalog\Models\Inventory;
|
use App\Domains\Catalog\Models\Inventory;
|
||||||
use App\Domains\Catalog\Models\ItemAttribute;
|
use App\Domains\Catalog\Models\ItemAttribute;
|
||||||
use App\Domains\Catalog\Models\Variant;
|
use App\Domains\Catalog\Models\Variant;
|
||||||
|
use App\Domains\Catalog\Services\CatalogService;
|
||||||
use App\Domains\Tenant\Models\Tenant;
|
use App\Domains\Tenant\Models\Tenant;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
@@ -20,6 +21,8 @@ class FoodService
|
|||||||
{
|
{
|
||||||
private const ATTRIBUTE_CODES = ['event_date', 'horario', 'servicio'];
|
private const ATTRIBUTE_CODES = ['event_date', 'horario', 'servicio'];
|
||||||
|
|
||||||
|
public function __construct(private readonly CatalogService $catalogService) {}
|
||||||
|
|
||||||
public function current(Tenant $tenant): ?CatalogItem
|
public function current(Tenant $tenant): ?CatalogItem
|
||||||
{
|
{
|
||||||
return CatalogItem::query()
|
return CatalogItem::query()
|
||||||
@@ -87,6 +90,18 @@ class FoodService
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function delete(Tenant $tenant, int $foodId): void
|
||||||
|
{
|
||||||
|
$variant = Variant::query()
|
||||||
|
->whereKey($foodId)
|
||||||
|
->whereHas('catalogItem', fn ($query) => $query
|
||||||
|
->where('tenant_code', $tenant->codigo)
|
||||||
|
->where('slug', 'comida'))
|
||||||
|
->firstOrFail();
|
||||||
|
|
||||||
|
$this->catalogService->deleteVariant($variant);
|
||||||
|
}
|
||||||
|
|
||||||
/** @return Collection<string, Attribute> */
|
/** @return Collection<string, Attribute> */
|
||||||
private function attributes(Tenant $tenant): Collection
|
private function attributes(Tenant $tenant): Collection
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ use App\Domains\Catalog\Models\Category;
|
|||||||
use App\Domains\Catalog\Models\Inventory;
|
use App\Domains\Catalog\Models\Inventory;
|
||||||
use App\Domains\Catalog\Models\ItemAttribute;
|
use App\Domains\Catalog\Models\ItemAttribute;
|
||||||
use App\Domains\Catalog\Models\Variant;
|
use App\Domains\Catalog\Models\Variant;
|
||||||
|
use App\Domains\Catalog\Services\CatalogService;
|
||||||
use App\Domains\Tenant\Models\Tenant;
|
use App\Domains\Tenant\Models\Tenant;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
@@ -21,6 +22,8 @@ class MerchandiseService
|
|||||||
{
|
{
|
||||||
private const ATTRIBUTE_CODES = ['color', 'talle'];
|
private const ATTRIBUTE_CODES = ['color', 'talle'];
|
||||||
|
|
||||||
|
public function __construct(private readonly CatalogService $catalogService) {}
|
||||||
|
|
||||||
/** @return Collection<int, CatalogItem> */
|
/** @return Collection<int, CatalogItem> */
|
||||||
public function all(Tenant $tenant): Collection
|
public function all(Tenant $tenant): Collection
|
||||||
{
|
{
|
||||||
@@ -120,6 +123,20 @@ class MerchandiseService
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function delete(Tenant $tenant, int $merchandiseId): void
|
||||||
|
{
|
||||||
|
$variant = Variant::query()
|
||||||
|
->whereKey($merchandiseId)
|
||||||
|
->whereHas('catalogItem', fn ($query) => $query
|
||||||
|
->where('tenant_code', $tenant->codigo)
|
||||||
|
->where('event_product_type', EventProductType::Product->value)
|
||||||
|
->whereHas('category', fn ($categoryQuery) => $categoryQuery
|
||||||
|
->where('nombre', 'Merchandising')))
|
||||||
|
->firstOrFail();
|
||||||
|
|
||||||
|
$this->catalogService->deleteVariant($variant);
|
||||||
|
}
|
||||||
|
|
||||||
/** @return Collection<string, Attribute> */
|
/** @return Collection<string, Attribute> */
|
||||||
private function attributes(Tenant $tenant): Collection
|
private function attributes(Tenant $tenant): Collection
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,22 +15,34 @@ Route::prefix('v1/adminapp/tenant')
|
|||||||
Route::post('entries', [EntryController::class, 'store'])
|
Route::post('entries', [EntryController::class, 'store'])
|
||||||
->middleware('tenant.menu:adminapp.fiesta-futbol-infantil.entradas')
|
->middleware('tenant.menu:adminapp.fiesta-futbol-infantil.entradas')
|
||||||
->name('adminapp.fiesta-futbol-infantil.entries.store');
|
->name('adminapp.fiesta-futbol-infantil.entries.store');
|
||||||
|
Route::delete('entries/{entry}', [EntryController::class, 'destroy'])
|
||||||
|
->middleware('tenant.menu:adminapp.fiesta-futbol-infantil.entradas')
|
||||||
|
->name('adminapp.fiesta-futbol-infantil.entries.destroy');
|
||||||
Route::get('foods', [FoodController::class, 'index'])
|
Route::get('foods', [FoodController::class, 'index'])
|
||||||
->middleware('tenant.menu:adminapp.fiesta-futbol-infantil.comida')
|
->middleware('tenant.menu:adminapp.fiesta-futbol-infantil.comida')
|
||||||
->name('adminapp.fiesta-futbol-infantil.foods.index');
|
->name('adminapp.fiesta-futbol-infantil.foods.index');
|
||||||
Route::post('foods', [FoodController::class, 'store'])
|
Route::post('foods', [FoodController::class, 'store'])
|
||||||
->middleware('tenant.menu:adminapp.fiesta-futbol-infantil.comida')
|
->middleware('tenant.menu:adminapp.fiesta-futbol-infantil.comida')
|
||||||
->name('adminapp.fiesta-futbol-infantil.foods.store');
|
->name('adminapp.fiesta-futbol-infantil.foods.store');
|
||||||
|
Route::delete('foods/{food}', [FoodController::class, 'destroy'])
|
||||||
|
->middleware('tenant.menu:adminapp.fiesta-futbol-infantil.comida')
|
||||||
|
->name('adminapp.fiesta-futbol-infantil.foods.destroy');
|
||||||
Route::get('accommodations', [AccommodationController::class, 'index'])
|
Route::get('accommodations', [AccommodationController::class, 'index'])
|
||||||
->middleware('tenant.menu:adminapp.fiesta-futbol-infantil.alojamientos')
|
->middleware('tenant.menu:adminapp.fiesta-futbol-infantil.alojamientos')
|
||||||
->name('adminapp.fiesta-futbol-infantil.accommodations.index');
|
->name('adminapp.fiesta-futbol-infantil.accommodations.index');
|
||||||
Route::post('accommodations', [AccommodationController::class, 'store'])
|
Route::post('accommodations', [AccommodationController::class, 'store'])
|
||||||
->middleware('tenant.menu:adminapp.fiesta-futbol-infantil.alojamientos')
|
->middleware('tenant.menu:adminapp.fiesta-futbol-infantil.alojamientos')
|
||||||
->name('adminapp.fiesta-futbol-infantil.accommodations.store');
|
->name('adminapp.fiesta-futbol-infantil.accommodations.store');
|
||||||
|
Route::delete('accommodations/{accommodation}', [AccommodationController::class, 'destroy'])
|
||||||
|
->middleware('tenant.menu:adminapp.fiesta-futbol-infantil.alojamientos')
|
||||||
|
->name('adminapp.fiesta-futbol-infantil.accommodations.destroy');
|
||||||
Route::get('merchandise', [MerchandiseController::class, 'index'])
|
Route::get('merchandise', [MerchandiseController::class, 'index'])
|
||||||
->middleware('tenant.menu:adminapp.fiesta-futbol-infantil.merchandising')
|
->middleware('tenant.menu:adminapp.fiesta-futbol-infantil.merchandising')
|
||||||
->name('adminapp.fiesta-futbol-infantil.merchandise.index');
|
->name('adminapp.fiesta-futbol-infantil.merchandise.index');
|
||||||
Route::post('merchandise', [MerchandiseController::class, 'store'])
|
Route::post('merchandise', [MerchandiseController::class, 'store'])
|
||||||
->middleware('tenant.menu:adminapp.fiesta-futbol-infantil.merchandising')
|
->middleware('tenant.menu:adminapp.fiesta-futbol-infantil.merchandising')
|
||||||
->name('adminapp.fiesta-futbol-infantil.merchandise.store');
|
->name('adminapp.fiesta-futbol-infantil.merchandise.store');
|
||||||
|
Route::delete('merchandise/{merchandise}', [MerchandiseController::class, 'destroy'])
|
||||||
|
->middleware('tenant.menu:adminapp.fiesta-futbol-infantil.merchandising')
|
||||||
|
->name('adminapp.fiesta-futbol-infantil.merchandise.destroy');
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -125,6 +125,25 @@ class AccommodationControllerTest extends TestCase
|
|||||||
$this->assertDatabaseCount('variantes', 2);
|
$this->assertDatabaseCount('variantes', 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_it_deletes_an_accommodation_and_its_empty_product(): void
|
||||||
|
{
|
||||||
|
[$tenant] = $this->configuredTenant();
|
||||||
|
Sanctum::actingAs($this->createAdminAppUser($tenant));
|
||||||
|
|
||||||
|
$accommodationId = $this->postJson('/api/v1/adminapp/tenant/accommodations', [
|
||||||
|
'variants' => [
|
||||||
|
$this->variantPayload('Carpa', null, 100, 35000),
|
||||||
|
],
|
||||||
|
])->assertOk()->json('data.variants.0.id');
|
||||||
|
|
||||||
|
$this->deleteJson("/api/v1/adminapp/tenant/accommodations/{$accommodationId}")
|
||||||
|
->assertNoContent();
|
||||||
|
|
||||||
|
$this->assertDatabaseCount('catalog_items', 0);
|
||||||
|
$this->assertDatabaseCount('variantes', 0);
|
||||||
|
$this->assertDatabaseCount('inventories', 0);
|
||||||
|
}
|
||||||
|
|
||||||
public function test_it_rejects_duplicate_normalized_titles(): void
|
public function test_it_rejects_duplicate_normalized_titles(): void
|
||||||
{
|
{
|
||||||
[$tenant] = $this->configuredTenant();
|
[$tenant] = $this->configuredTenant();
|
||||||
|
|||||||
@@ -168,6 +168,35 @@ class EntryControllerTest extends TestCase
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_it_deletes_an_entry_and_its_inventory(): void
|
||||||
|
{
|
||||||
|
$tenant = $this->createFiestaTenant();
|
||||||
|
$this->createEventDateAttribute($tenant);
|
||||||
|
$eventDate = $tenant->eventDates()->create([
|
||||||
|
'date' => '2026-10-09',
|
||||||
|
'time_start' => '00:00',
|
||||||
|
'time_end' => '23:59',
|
||||||
|
]);
|
||||||
|
Sanctum::actingAs($this->createAdminAppUser($tenant));
|
||||||
|
|
||||||
|
$entryId = $this->postJson('/api/v1/adminapp/tenant/entries', [
|
||||||
|
'entries' => [[
|
||||||
|
'title' => 'Entrada diaria',
|
||||||
|
'description' => null,
|
||||||
|
'event_date_ids' => [$eventDate->id],
|
||||||
|
'stock' => 100,
|
||||||
|
'price' => 5000,
|
||||||
|
]],
|
||||||
|
])->assertOk()->json('data.0.id');
|
||||||
|
|
||||||
|
$this->deleteJson("/api/v1/adminapp/tenant/entries/{$entryId}")
|
||||||
|
->assertNoContent();
|
||||||
|
|
||||||
|
$this->assertDatabaseCount('catalog_items', 0);
|
||||||
|
$this->assertDatabaseCount('variantes', 0);
|
||||||
|
$this->assertDatabaseCount('inventories', 0);
|
||||||
|
}
|
||||||
|
|
||||||
public function test_dates_must_belong_to_the_authenticated_tenant(): void
|
public function test_dates_must_belong_to_the_authenticated_tenant(): void
|
||||||
{
|
{
|
||||||
$tenant = $this->createFiestaTenant();
|
$tenant = $this->createFiestaTenant();
|
||||||
|
|||||||
@@ -123,6 +123,39 @@ class FoodControllerTest extends TestCase
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_it_deletes_food_records_and_removes_the_empty_product(): void
|
||||||
|
{
|
||||||
|
[$tenant, $firstDate, $secondDate] = $this->configuredTenant();
|
||||||
|
Sanctum::actingAs($this->createAdminAppUser($tenant));
|
||||||
|
|
||||||
|
$created = $this->postJson('/api/v1/adminapp/tenant/foods', [
|
||||||
|
'variants' => [
|
||||||
|
$this->variantPayload($firstDate->id, 'Almuerzo', 'Comedor', 100, 10000),
|
||||||
|
$this->variantPayload($secondDate->id, 'Cena', 'Vianda', 50, 8000),
|
||||||
|
],
|
||||||
|
])->assertOk();
|
||||||
|
$firstId = $created->json('data.variants.0.id');
|
||||||
|
$secondId = $created->json('data.variants.1.id');
|
||||||
|
|
||||||
|
$this->deleteJson("/api/v1/adminapp/tenant/foods/{$secondId}")
|
||||||
|
->assertNoContent();
|
||||||
|
|
||||||
|
$this->assertDatabaseHas('catalog_items', [
|
||||||
|
'tenant_code' => $tenant->codigo,
|
||||||
|
'slug' => 'comida',
|
||||||
|
'precio' => 10000,
|
||||||
|
]);
|
||||||
|
$this->assertDatabaseCount('variantes', 1);
|
||||||
|
$this->assertDatabaseCount('inventories', 1);
|
||||||
|
|
||||||
|
$this->deleteJson("/api/v1/adminapp/tenant/foods/{$firstId}")
|
||||||
|
->assertNoContent();
|
||||||
|
|
||||||
|
$this->assertDatabaseCount('catalog_items', 0);
|
||||||
|
$this->assertDatabaseCount('variantes', 0);
|
||||||
|
$this->assertDatabaseCount('inventories', 0);
|
||||||
|
}
|
||||||
|
|
||||||
public function test_it_rejects_duplicate_combinations(): void
|
public function test_it_rejects_duplicate_combinations(): void
|
||||||
{
|
{
|
||||||
[$tenant, $firstDate] = $this->configuredTenant();
|
[$tenant, $firstDate] = $this->configuredTenant();
|
||||||
|
|||||||
@@ -139,6 +139,40 @@ class MerchandiseControllerTest extends TestCase
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_it_deletes_merchandise_records_and_removes_the_empty_item(): void
|
||||||
|
{
|
||||||
|
[$tenant] = $this->configuredTenant();
|
||||||
|
Sanctum::actingAs($this->createAdminAppUser($tenant));
|
||||||
|
|
||||||
|
$created = $this->postJson('/api/v1/adminapp/tenant/merchandise', [
|
||||||
|
'items' => [
|
||||||
|
$this->itemPayload('Camiseta', 3, [
|
||||||
|
$this->variantPayload('Verde', 'S', 100, 10000),
|
||||||
|
$this->variantPayload('Blanco', 'M', 50, 15000),
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
])->assertOk();
|
||||||
|
$itemId = $created->json('data.0.id');
|
||||||
|
$firstId = $created->json('data.0.variants.0.id');
|
||||||
|
$secondId = $created->json('data.0.variants.1.id');
|
||||||
|
|
||||||
|
$this->deleteJson("/api/v1/adminapp/tenant/merchandise/{$firstId}")
|
||||||
|
->assertNoContent();
|
||||||
|
|
||||||
|
$this->assertDatabaseHas('catalog_items', [
|
||||||
|
'id' => $itemId,
|
||||||
|
'precio' => 15000,
|
||||||
|
]);
|
||||||
|
$this->assertDatabaseCount('variantes', 1);
|
||||||
|
|
||||||
|
$this->deleteJson("/api/v1/adminapp/tenant/merchandise/{$secondId}")
|
||||||
|
->assertNoContent();
|
||||||
|
|
||||||
|
$this->assertDatabaseMissing('catalog_items', ['id' => $itemId]);
|
||||||
|
$this->assertDatabaseCount('variantes', 0);
|
||||||
|
$this->assertDatabaseCount('inventories', 0);
|
||||||
|
}
|
||||||
|
|
||||||
public function test_it_rejects_duplicate_color_and_size_combinations(): void
|
public function test_it_rejects_duplicate_color_and_size_combinations(): void
|
||||||
{
|
{
|
||||||
[$tenant] = $this->configuredTenant();
|
[$tenant] = $this->configuredTenant();
|
||||||
|
|||||||
Reference in New Issue
Block a user