feat: implement index methods for Accommodation, Entry, Food, and Merchandise controllers; add service methods for fetching current items
This commit is contained in:
@@ -6,11 +6,19 @@ use App\Domains\FiestaFutbolInfantil\Requests\UpsertAccommodationVariantsRequest
|
|||||||
use App\Domains\FiestaFutbolInfantil\Resources\AccommodationResource;
|
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;
|
||||||
|
|
||||||
class AccommodationController extends Controller
|
class AccommodationController extends Controller
|
||||||
{
|
{
|
||||||
public function __construct(private readonly AccommodationService $accommodationService) {}
|
public function __construct(private readonly AccommodationService $accommodationService) {}
|
||||||
|
|
||||||
|
public function index(Request $request): AccommodationResource
|
||||||
|
{
|
||||||
|
return AccommodationResource::make(
|
||||||
|
$this->accommodationService->current($request->user()->tenant()->firstOrFail())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function store(UpsertAccommodationVariantsRequest $request): AccommodationResource
|
public function store(UpsertAccommodationVariantsRequest $request): AccommodationResource
|
||||||
{
|
{
|
||||||
$tenant = $request->user()->tenant()->firstOrFail();
|
$tenant = $request->user()->tenant()->firstOrFail();
|
||||||
|
|||||||
@@ -7,11 +7,20 @@ use App\Domains\FiestaFutbolInfantil\Resources\EntryResource;
|
|||||||
use App\Domains\FiestaFutbolInfantil\Services\EntryService;
|
use App\Domains\FiestaFutbolInfantil\Services\EntryService;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
|
||||||
|
|
||||||
class EntryController extends Controller
|
class EntryController extends Controller
|
||||||
{
|
{
|
||||||
public function __construct(private readonly EntryService $entryService) {}
|
public function __construct(private readonly EntryService $entryService) {}
|
||||||
|
|
||||||
|
public function index(Request $request): AnonymousResourceCollection
|
||||||
|
{
|
||||||
|
return EntryResource::collection(
|
||||||
|
$this->entryService->all($request->user()->tenant()->firstOrFail())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function store(UpsertEntriesRequest $request): JsonResponse
|
public function store(UpsertEntriesRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$tenant = $request->user()->tenant()->firstOrFail();
|
$tenant = $request->user()->tenant()->firstOrFail();
|
||||||
|
|||||||
@@ -6,11 +6,19 @@ use App\Domains\FiestaFutbolInfantil\Requests\UpsertFoodVariantsRequest;
|
|||||||
use App\Domains\FiestaFutbolInfantil\Resources\FoodResource;
|
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;
|
||||||
|
|
||||||
class FoodController extends Controller
|
class FoodController extends Controller
|
||||||
{
|
{
|
||||||
public function __construct(private readonly FoodService $foodService) {}
|
public function __construct(private readonly FoodService $foodService) {}
|
||||||
|
|
||||||
|
public function index(Request $request): FoodResource
|
||||||
|
{
|
||||||
|
return FoodResource::make(
|
||||||
|
$this->foodService->current($request->user()->tenant()->firstOrFail())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function store(UpsertFoodVariantsRequest $request): FoodResource
|
public function store(UpsertFoodVariantsRequest $request): FoodResource
|
||||||
{
|
{
|
||||||
$tenant = $request->user()->tenant()->firstOrFail();
|
$tenant = $request->user()->tenant()->firstOrFail();
|
||||||
|
|||||||
@@ -7,11 +7,20 @@ use App\Domains\FiestaFutbolInfantil\Resources\MerchandiseResource;
|
|||||||
use App\Domains\FiestaFutbolInfantil\Services\MerchandiseService;
|
use App\Domains\FiestaFutbolInfantil\Services\MerchandiseService;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
|
||||||
|
|
||||||
class MerchandiseController extends Controller
|
class MerchandiseController extends Controller
|
||||||
{
|
{
|
||||||
public function __construct(private readonly MerchandiseService $merchandiseService) {}
|
public function __construct(private readonly MerchandiseService $merchandiseService) {}
|
||||||
|
|
||||||
|
public function index(Request $request): AnonymousResourceCollection
|
||||||
|
{
|
||||||
|
return MerchandiseResource::collection(
|
||||||
|
$this->merchandiseService->all($request->user()->tenant()->firstOrFail())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function store(UpsertMerchandiseRequest $request): JsonResponse
|
public function store(UpsertMerchandiseRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$tenant = $request->user()->tenant()->firstOrFail();
|
$tenant = $request->user()->tenant()->firstOrFail();
|
||||||
|
|||||||
@@ -20,6 +20,20 @@ class AccommodationService
|
|||||||
{
|
{
|
||||||
private const ATTRIBUTE_CODE = 'tipo_alojamiento';
|
private const ATTRIBUTE_CODE = 'tipo_alojamiento';
|
||||||
|
|
||||||
|
public function current(Tenant $tenant): CatalogItem
|
||||||
|
{
|
||||||
|
return CatalogItem::query()
|
||||||
|
->where('tenant_code', $tenant->codigo)
|
||||||
|
->where('slug', 'alojamiento')
|
||||||
|
->with([
|
||||||
|
'itemAttributes.attribute.options',
|
||||||
|
'variants.catalogItem',
|
||||||
|
'variants.inventory',
|
||||||
|
'variants.definitions',
|
||||||
|
])
|
||||||
|
->firstOrFail();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array<int, array<string, mixed>> $variants
|
* @param array<int, array<string, mixed>> $variants
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -19,6 +19,21 @@ class EntryService
|
|||||||
{
|
{
|
||||||
public function __construct(private readonly CatalogService $catalogService) {}
|
public function __construct(private readonly CatalogService $catalogService) {}
|
||||||
|
|
||||||
|
/** @return Collection<int, CatalogItem> */
|
||||||
|
public function all(Tenant $tenant): Collection
|
||||||
|
{
|
||||||
|
return CatalogItem::query()
|
||||||
|
->where('tenant_code', $tenant->codigo)
|
||||||
|
->where('event_product_type', EventProductType::Entry->value)
|
||||||
|
->with([
|
||||||
|
'variants.inventory',
|
||||||
|
'variants.eventDate',
|
||||||
|
'variants.eventDates',
|
||||||
|
])
|
||||||
|
->orderBy('id')
|
||||||
|
->get();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array<int, array<string, mixed>> $entries
|
* @param array<int, array<string, mixed>> $entries
|
||||||
* @return Collection<int, CatalogItem>
|
* @return Collection<int, CatalogItem>
|
||||||
|
|||||||
@@ -20,6 +20,21 @@ class FoodService
|
|||||||
{
|
{
|
||||||
private const ATTRIBUTE_CODES = ['event_date', 'horario', 'servicio'];
|
private const ATTRIBUTE_CODES = ['event_date', 'horario', 'servicio'];
|
||||||
|
|
||||||
|
public function current(Tenant $tenant): CatalogItem
|
||||||
|
{
|
||||||
|
return CatalogItem::query()
|
||||||
|
->where('tenant_code', $tenant->codigo)
|
||||||
|
->where('slug', 'comida')
|
||||||
|
->with([
|
||||||
|
'variants.catalogItem',
|
||||||
|
'variants.inventory',
|
||||||
|
'variants.eventDate',
|
||||||
|
'variants.eventDates',
|
||||||
|
'variants.definitions.itemAttribute.attribute',
|
||||||
|
])
|
||||||
|
->firstOrFail();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array<int, array<string, mixed>> $variants
|
* @param array<int, array<string, mixed>> $variants
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -21,6 +21,23 @@ class MerchandiseService
|
|||||||
{
|
{
|
||||||
private const ATTRIBUTE_CODES = ['color', 'talle'];
|
private const ATTRIBUTE_CODES = ['color', 'talle'];
|
||||||
|
|
||||||
|
/** @return Collection<int, CatalogItem> */
|
||||||
|
public function all(Tenant $tenant): Collection
|
||||||
|
{
|
||||||
|
return CatalogItem::query()
|
||||||
|
->where('tenant_code', $tenant->codigo)
|
||||||
|
->where('event_product_type', EventProductType::Product->value)
|
||||||
|
->whereHas('category', fn ($query) => $query->where('nombre', 'Merchandising'))
|
||||||
|
->with([
|
||||||
|
'itemAttributes.attribute.options',
|
||||||
|
'variants.catalogItem',
|
||||||
|
'variants.inventory',
|
||||||
|
'variants.definitions',
|
||||||
|
])
|
||||||
|
->orderBy('id')
|
||||||
|
->get();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array<int, array<string, mixed>> $items
|
* @param array<int, array<string, mixed>> $items
|
||||||
* @return Collection<int, CatalogItem>
|
* @return Collection<int, CatalogItem>
|
||||||
|
|||||||
@@ -9,15 +9,27 @@ use Illuminate\Support\Facades\Route;
|
|||||||
Route::prefix('v1/adminapp/tenant')
|
Route::prefix('v1/adminapp/tenant')
|
||||||
->middleware(['auth:sanctum', 'adminapp.tenant'])
|
->middleware(['auth:sanctum', 'adminapp.tenant'])
|
||||||
->group(function (): void {
|
->group(function (): void {
|
||||||
|
Route::get('entries', [EntryController::class, 'index'])
|
||||||
|
->middleware('tenant.menu:adminapp.fiesta-futbol-infantil.entradas')
|
||||||
|
->name('adminapp.fiesta-futbol-infantil.entries.index');
|
||||||
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::get('foods', [FoodController::class, 'index'])
|
||||||
|
->middleware('tenant.menu:adminapp.fiesta-futbol-infantil.comida')
|
||||||
|
->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::get('accommodations', [AccommodationController::class, 'index'])
|
||||||
|
->middleware('tenant.menu:adminapp.fiesta-futbol-infantil.alojamientos')
|
||||||
|
->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::get('merchandise', [MerchandiseController::class, 'index'])
|
||||||
|
->middleware('tenant.menu:adminapp.fiesta-futbol-infantil.merchandising')
|
||||||
|
->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');
|
||||||
|
|||||||
@@ -57,6 +57,13 @@ class AccommodationControllerTest extends TestCase
|
|||||||
->assertJsonPath('data.variants.0.stock', 25)
|
->assertJsonPath('data.variants.0.stock', 25)
|
||||||
->assertJsonPath('data.variants.0.price', '45000.00');
|
->assertJsonPath('data.variants.0.price', '45000.00');
|
||||||
|
|
||||||
|
$this->getJson('/api/v1/adminapp/tenant/accommodations')
|
||||||
|
->assertOk()
|
||||||
|
->assertJsonPath('data.name', 'Alojamiento')
|
||||||
|
->assertJsonCount(2, 'data.variants')
|
||||||
|
->assertJsonPath('data.variants.0.title', 'Casa Rodante Familiar')
|
||||||
|
->assertJsonPath('data.variants.1.title', 'Carpa');
|
||||||
|
|
||||||
$this->assertDatabaseHas('attribute_options', [
|
$this->assertDatabaseHas('attribute_options', [
|
||||||
'attribute_id' => $attribute->id,
|
'attribute_id' => $attribute->id,
|
||||||
'value' => 'casa_rodante_familiar',
|
'value' => 'casa_rodante_familiar',
|
||||||
|
|||||||
@@ -80,6 +80,13 @@ class EntryControllerTest extends TestCase
|
|||||||
->assertJsonPath('data.1.title', 'Entrada diaria')
|
->assertJsonPath('data.1.title', 'Entrada diaria')
|
||||||
->assertJsonPath('data.1.price', '5000.50');
|
->assertJsonPath('data.1.price', '5000.50');
|
||||||
|
|
||||||
|
$this->getJson('/api/v1/adminapp/tenant/entries')
|
||||||
|
->assertOk()
|
||||||
|
->assertJsonCount(2, 'data')
|
||||||
|
->assertJsonPath('data.0.title', 'Abono')
|
||||||
|
->assertJsonPath('data.0.event_date_ids', [$firstDate->id, $secondDate->id])
|
||||||
|
->assertJsonPath('data.1.title', 'Entrada diaria');
|
||||||
|
|
||||||
$this->assertDatabaseCount('catalog_items', 2);
|
$this->assertDatabaseCount('catalog_items', 2);
|
||||||
$this->assertDatabaseCount('variantes', 2);
|
$this->assertDatabaseCount('variantes', 2);
|
||||||
$this->assertDatabaseCount('inventories', 2);
|
$this->assertDatabaseCount('inventories', 2);
|
||||||
|
|||||||
@@ -56,6 +56,13 @@ class FoodControllerTest extends TestCase
|
|||||||
->assertJsonPath('data.variants.0.price', '10000.00')
|
->assertJsonPath('data.variants.0.price', '10000.00')
|
||||||
->assertJsonPath('data.variants.1.price', '8000.00');
|
->assertJsonPath('data.variants.1.price', '8000.00');
|
||||||
|
|
||||||
|
$this->getJson('/api/v1/adminapp/tenant/foods')
|
||||||
|
->assertOk()
|
||||||
|
->assertJsonPath('data.name', 'Comida')
|
||||||
|
->assertJsonCount(2, 'data.variants')
|
||||||
|
->assertJsonPath('data.variants.0.schedule', 'Almuerzo')
|
||||||
|
->assertJsonPath('data.variants.1.service', 'Vianda');
|
||||||
|
|
||||||
$this->assertDatabaseCount('catalog_items', 1);
|
$this->assertDatabaseCount('catalog_items', 1);
|
||||||
$this->assertDatabaseCount('variantes', 2);
|
$this->assertDatabaseCount('variantes', 2);
|
||||||
$this->assertDatabaseCount('inventories', 2);
|
$this->assertDatabaseCount('inventories', 2);
|
||||||
|
|||||||
@@ -67,6 +67,14 @@ class MerchandiseControllerTest extends TestCase
|
|||||||
->assertJsonPath('data.0.variants.2.color', 'Azul Marino')
|
->assertJsonPath('data.0.variants.2.color', 'Azul Marino')
|
||||||
->assertJsonPath('data.0.variants.2.color_value', 'azul_marino');
|
->assertJsonPath('data.0.variants.2.color_value', 'azul_marino');
|
||||||
|
|
||||||
|
$this->getJson('/api/v1/adminapp/tenant/merchandise')
|
||||||
|
->assertOk()
|
||||||
|
->assertJsonCount(2, 'data')
|
||||||
|
->assertJsonPath('data.0.title', 'Camiseta')
|
||||||
|
->assertJsonCount(3, 'data.0.variants')
|
||||||
|
->assertJsonPath('data.1.title', 'Buzo')
|
||||||
|
->assertJsonPath('data.1.variants.0.size', 'XL');
|
||||||
|
|
||||||
$this->assertDatabaseCount('catalog_items', 2);
|
$this->assertDatabaseCount('catalog_items', 2);
|
||||||
$this->assertDatabaseCount('variantes', 4);
|
$this->assertDatabaseCount('variantes', 4);
|
||||||
$this->assertDatabaseCount('inventories', 4);
|
$this->assertDatabaseCount('inventories', 4);
|
||||||
|
|||||||
Reference in New Issue
Block a user