diff --git a/app/Domains/FiestaFutbolInfantil/Controllers/CategoryVisibilityController.php b/app/Domains/FiestaFutbolInfantil/Controllers/CategoryVisibilityController.php new file mode 100644 index 0000000..26d6f7f --- /dev/null +++ b/app/Domains/FiestaFutbolInfantil/Controllers/CategoryVisibilityController.php @@ -0,0 +1,49 @@ +category($request); + $tenant = $request->user()->tenant()->firstOrFail(); + + return response()->json([ + 'data' => [ + 'is_enabled' => $this->visibilityService->isEnabled($tenant, $category), + ], + ]); + } + + public function update(UpdateCategoryVisibilityRequest $request): JsonResponse + { + $category = $this->category($request); + $tenant = $request->user()->tenant()->firstOrFail(); + $model = $this->visibilityService->update( + $tenant, + $category, + $request->boolean('is_enabled'), + ); + + return response()->json([ + 'data' => [ + 'is_enabled' => $model->is_enabled, + ], + ]); + } + + private function category(Request $request): FiestaCategory + { + return FiestaCategory::from((string) $request->route('category')); + } +} diff --git a/app/Domains/FiestaFutbolInfantil/Enums/FiestaCategory.php b/app/Domains/FiestaFutbolInfantil/Enums/FiestaCategory.php new file mode 100644 index 0000000..652e4a8 --- /dev/null +++ b/app/Domains/FiestaFutbolInfantil/Enums/FiestaCategory.php @@ -0,0 +1,21 @@ + 'Entradas', + self::Foods => 'Comidas', + self::Accommodations => 'Alojamientos', + self::Merchandise => 'Merchandising', + }; + } +} diff --git a/app/Domains/FiestaFutbolInfantil/Requests/UpdateCategoryVisibilityRequest.php b/app/Domains/FiestaFutbolInfantil/Requests/UpdateCategoryVisibilityRequest.php new file mode 100644 index 0000000..49def22 --- /dev/null +++ b/app/Domains/FiestaFutbolInfantil/Requests/UpdateCategoryVisibilityRequest.php @@ -0,0 +1,16 @@ + */ + public function rules(): array + { + return [ + 'is_enabled' => ['required', 'boolean'], + ]; + } +} diff --git a/app/Domains/FiestaFutbolInfantil/Services/CategoryVisibilityService.php b/app/Domains/FiestaFutbolInfantil/Services/CategoryVisibilityService.php new file mode 100644 index 0000000..d1fb4d5 --- /dev/null +++ b/app/Domains/FiestaFutbolInfantil/Services/CategoryVisibilityService.php @@ -0,0 +1,29 @@ +where('tenant_code', $tenant->codigo) + ->where('nombre', $category->categoryName()) + ->value('is_enabled') ?? true; + } + + public function update(Tenant $tenant, FiestaCategory $category, bool $isEnabled): Category + { + $model = Category::query()->firstOrCreate([ + 'tenant_code' => $tenant->codigo, + 'nombre' => $category->categoryName(), + ]); + $model->update(['is_enabled' => $isEnabled]); + + return $model; + } +} diff --git a/app/Domains/FiestaFutbolInfantil/routes/api.php b/app/Domains/FiestaFutbolInfantil/routes/api.php index 86065e8..39d4a47 100644 --- a/app/Domains/FiestaFutbolInfantil/routes/api.php +++ b/app/Domains/FiestaFutbolInfantil/routes/api.php @@ -1,6 +1,7 @@ middleware(['auth:sanctum', 'adminapp.tenant']) ->group(function (): void { + $visibilityRoutes = static function (string $endpoint, string $category, string $menuCode): void { + Route::get("{$endpoint}/visibility", [CategoryVisibilityController::class, 'show']) + ->defaults('category', $category) + ->middleware("tenant.menu:{$menuCode}"); + Route::patch("{$endpoint}/visibility", [CategoryVisibilityController::class, 'update']) + ->defaults('category', $category) + ->middleware("tenant.menu:{$menuCode}"); + }; + + $visibilityRoutes('entries', 'entries', 'adminapp.fiesta-futbol-infantil.entradas'); + $visibilityRoutes('foods', 'foods', 'adminapp.fiesta-futbol-infantil.comida'); + $visibilityRoutes('accommodations', 'accommodations', 'adminapp.fiesta-futbol-infantil.alojamientos'); + $visibilityRoutes('merchandise', 'merchandise', 'adminapp.fiesta-futbol-infantil.merchandising'); + Route::get('entries', [EntryController::class, 'index']) ->middleware('tenant.menu:adminapp.fiesta-futbol-infantil.entradas') ->name('adminapp.fiesta-futbol-infantil.entries.index'); diff --git a/tests/Feature/FiestaFutbolInfantil/EntryControllerTest.php b/tests/Feature/FiestaFutbolInfantil/EntryControllerTest.php index 3a66f36..4cc9a7b 100644 --- a/tests/Feature/FiestaFutbolInfantil/EntryControllerTest.php +++ b/tests/Feature/FiestaFutbolInfantil/EntryControllerTest.php @@ -38,6 +38,45 @@ class EntryControllerTest extends TestCase ->assertUnauthorized(); } + public function test_category_visibility_can_be_read_and_updated_for_every_fiesta_menu(): void + { + $tenant = $this->createFiestaTenant(); + $categories = [ + 'entries' => ['Entradas', 'adminapp.fiesta-futbol-infantil.entradas'], + 'foods' => ['Comidas', 'adminapp.fiesta-futbol-infantil.comida'], + 'accommodations' => ['Alojamientos', 'adminapp.fiesta-futbol-infantil.alojamientos'], + 'merchandise' => ['Merchandising', 'adminapp.fiesta-futbol-infantil.merchandising'], + ]; + + foreach ($categories as [$label, $menuCode]) { + $menu = Menu::query()->firstOrCreate( + ['code' => $menuCode], + ['label' => $label, 'route' => '/admin'], + ); + $tenant->menues()->syncWithoutDetaching([$menu->code]); + } + + Sanctum::actingAs($this->createAdminAppUser($tenant)); + + foreach ($categories as $endpoint => [$categoryName]) { + $this->getJson("/api/v1/adminapp/tenant/{$endpoint}/visibility") + ->assertOk() + ->assertJsonPath('data.is_enabled', true); + + $this->patchJson("/api/v1/adminapp/tenant/{$endpoint}/visibility", [ + 'is_enabled' => false, + ]) + ->assertOk() + ->assertJsonPath('data.is_enabled', false); + + $this->assertDatabaseHas('categorias', [ + 'tenant_code' => $tenant->codigo, + 'nombre' => $categoryName, + 'is_enabled' => false, + ]); + } + } + public function test_it_creates_multiple_entries_with_dates_and_tracked_inventory(): void { $tenant = $this->createFiestaTenant();