diff --git a/app/Domains/Catalog/Controllers/AdminApp/OnTicketFeaturedGroupController.php b/app/Domains/Catalog/Controllers/AdminApp/OnTicketFeaturedGroupController.php deleted file mode 100644 index 7017d66..0000000 --- a/app/Domains/Catalog/Controllers/AdminApp/OnTicketFeaturedGroupController.php +++ /dev/null @@ -1,65 +0,0 @@ -featuredGroupService->forTenant($this->onTicketTenant($request)) - ); - } - - public function store(UpsertOnTicketFeaturedGroupRequest $request): JsonResponse - { - $featuredGroup = $this->featuredGroupService->create( - $this->onTicketTenant($request), - $request->validated(), - ); - - return OnTicketFeaturedGroupResource::make($featuredGroup) - ->response() - ->setStatusCode(201); - } - - public function update( - UpsertOnTicketFeaturedGroupRequest $request, - FeaturedGroup $featuredGroup, - ): OnTicketFeaturedGroupResource { - $tenant = $this->onTicketTenant($request); - - abort_unless($featuredGroup->tenant_code === $tenant->codigo, 404); - - return OnTicketFeaturedGroupResource::make( - $this->featuredGroupService->update( - $tenant, - $featuredGroup, - $request->validated(), - ) - ); - } - - private function onTicketTenant(Request $request): Tenant - { - $tenant = $request->user()->tenant()->firstOrFail(); - - abort_unless($tenant->website_type_code === 'onticket', 404); - - return $tenant; - } -} diff --git a/app/Domains/Catalog/Requests/AdminApp/UpsertOnTicketFeaturedGroupRequest.php b/app/Domains/Catalog/Requests/AdminApp/UpsertOnTicketFeaturedGroupRequest.php deleted file mode 100644 index 9d7423d..0000000 --- a/app/Domains/Catalog/Requests/AdminApp/UpsertOnTicketFeaturedGroupRequest.php +++ /dev/null @@ -1,22 +0,0 @@ - */ - public function rules(): array - { - return [ - 'category_name' => ['required', 'string', 'max:255'], - 'is_featured' => ['required', 'boolean'], - ]; - } -} diff --git a/app/Domains/Catalog/Resources/AdminApp/OnTicketFeaturedGroupResource.php b/app/Domains/Catalog/Resources/AdminApp/OnTicketFeaturedGroupResource.php deleted file mode 100644 index 6ef384b..0000000 --- a/app/Domains/Catalog/Resources/AdminApp/OnTicketFeaturedGroupResource.php +++ /dev/null @@ -1,29 +0,0 @@ - */ - public function toArray(Request $request): array - { - return [ - 'id' => $this->id, - 'code' => $this->code, - 'category_id' => $this->category_id, - 'category_name' => $this->category->nombre, - 'group_name' => $this->group_name, - 'is_featured' => $this->product_layout === ProductLayout::Row, - 'type' => $this->source_type->value, - 'product_layout' => $this->product_layout->value, - 'group_layout' => $this->group_layout->value, - 'order' => $this->group_order, - ]; - } -} diff --git a/app/Domains/Catalog/Services/OnTicketFeaturedGroupService.php b/app/Domains/Catalog/Services/OnTicketFeaturedGroupService.php deleted file mode 100644 index 6b2300a..0000000 --- a/app/Domains/Catalog/Services/OnTicketFeaturedGroupService.php +++ /dev/null @@ -1,95 +0,0 @@ - */ - public function forTenant(Tenant $tenant): Collection - { - return FeaturedGroup::query() - ->where('tenant_code', $tenant->codigo) - ->where('source_type', FeaturedGroupSource::Category) - ->whereHas('category', fn ($query) => $query->where('tenant_code', $tenant->codigo)) - ->with('category') - ->orderBy('group_order') - ->orderBy('id') - ->get(); - } - - /** @param array{category_name: string, is_featured: bool} $data */ - public function create(Tenant $tenant, array $data): FeaturedGroup - { - return DB::transaction(function () use ($tenant, $data): FeaturedGroup { - $category = $tenant->categories()->create([ - 'nombre' => $data['category_name'], - ]); - - $featuredGroup = FeaturedGroup::query()->create([ - 'tenant_code' => $tenant->codigo, - 'source_type' => FeaturedGroupSource::Category, - 'category_id' => $category->id, - 'product_layout' => $this->productLayout($data['is_featured']), - 'group_layout' => GroupLayout::Paginated, - 'group_name' => $data['category_name'], - 'group_order' => $this->nextOrder($tenant), - ]); - - return $featuredGroup->setRelation('category', $category); - }); - } - - /** @param array{category_name: string, is_featured: bool} $data */ - public function update( - Tenant $tenant, - FeaturedGroup $featuredGroup, - array $data, - ): FeaturedGroup { - return DB::transaction(function () use ($tenant, $featuredGroup, $data): FeaturedGroup { - $featuredGroup = FeaturedGroup::query() - ->whereKey($featuredGroup->getKey()) - ->where('tenant_code', $tenant->codigo) - ->where('source_type', FeaturedGroupSource::Category) - ->lockForUpdate() - ->firstOrFail(); - - $category = Category::query() - ->whereKey($featuredGroup->category_id) - ->where('tenant_code', $tenant->codigo) - ->lockForUpdate() - ->firstOrFail(); - - $category->update(['nombre' => $data['category_name']]); - $featuredGroup->update([ - 'group_name' => $data['category_name'], - 'product_layout' => $this->productLayout($data['is_featured']), - 'group_layout' => GroupLayout::Paginated, - ]); - - return $featuredGroup->setRelation('category', $category); - }); - } - - private function productLayout(bool $isFeatured): ProductLayout - { - return $isFeatured ? ProductLayout::Row : ProductLayout::ColumnWithCart; - } - - private function nextOrder(Tenant $tenant): int - { - $maximumOrder = FeaturedGroup::query() - ->where('tenant_code', $tenant->codigo) - ->max('group_order'); - - return $maximumOrder === null ? 0 : ((int) $maximumOrder) + 1; - } -} diff --git a/app/Domains/Catalog/routes/adminapp.php b/app/Domains/Catalog/routes/adminapp.php deleted file mode 100644 index 7a63fc2..0000000 --- a/app/Domains/Catalog/routes/adminapp.php +++ /dev/null @@ -1,15 +0,0 @@ -middleware(['auth:sanctum', 'adminapp.tenant']) - ->group(function (): void { - Route::get('featured-groups', [OnTicketFeaturedGroupController::class, 'index']) - ->name('adminapp.featured-groups.index'); - Route::post('featured-groups', [OnTicketFeaturedGroupController::class, 'store']) - ->name('adminapp.featured-groups.store'); - Route::put('featured-groups/{featuredGroup}', [OnTicketFeaturedGroupController::class, 'update']) - ->name('adminapp.featured-groups.update'); - }); diff --git a/tests/Feature/Catalog/OnTicketFeaturedGroupControllerTest.php b/tests/Feature/Catalog/OnTicketFeaturedGroupControllerTest.php deleted file mode 100644 index 1c251b6..0000000 --- a/tests/Feature/Catalog/OnTicketFeaturedGroupControllerTest.php +++ /dev/null @@ -1,266 +0,0 @@ -seed(AuthorizationSeeder::class); - WebsiteType::query()->create([ - 'codigo' => 'onticket', - 'nombre' => 'OnTicket', - ]); - WebsiteType::query()->create([ - 'codigo' => 'shopit', - 'nombre' => 'Shopit', - ]); - } - - public function test_authentication_is_required(): void - { - $this->getJson('/api/v1/adminapp/tenant/featured-groups')->assertUnauthorized(); - $this->postJson('/api/v1/adminapp/tenant/featured-groups', $this->payload()) - ->assertUnauthorized(); - $this->putJson('/api/v1/adminapp/tenant/featured-groups/1', $this->payload()) - ->assertUnauthorized(); - } - - public function test_index_returns_only_category_groups_for_the_onticket_tenant(): void - { - $tenant = $this->createTenant('acme'); - $otherTenant = $this->createTenant('other'); - $first = $this->createCategoryGroup($tenant, 'Food', order: 2); - $second = $this->createCategoryGroup($tenant, 'Tickets', order: 1); - $this->createCategoryGroup($otherTenant, 'Other tenant'); - FeaturedGroup::query()->create([ - 'tenant_code' => $tenant->codigo, - 'source_type' => FeaturedGroupSource::All, - 'product_layout' => ProductLayout::Row, - 'group_layout' => GroupLayout::Paginated, - 'group_name' => 'All products', - 'group_order' => 0, - ]); - Sanctum::actingAs($this->createAdminAppUser($tenant)); - - $this->getJson('/api/v1/adminapp/tenant/featured-groups') - ->assertOk() - ->assertJsonCount(2, 'data') - ->assertJsonPath('data.0.id', $second->id) - ->assertJsonPath('data.0.category_name', 'Tickets') - ->assertJsonPath('data.1.id', $first->id) - ->assertJsonMissing(['category_name' => 'Other tenant']) - ->assertJsonMissing(['group_name' => 'All products']); - } - - public function test_store_creates_a_category_and_a_featured_horizontal_group(): void - { - $tenant = $this->createTenant('acme'); - Sanctum::actingAs($this->createAdminAppUser($tenant)); - - $response = $this->postJson('/api/v1/adminapp/tenant/featured-groups', [ - 'category_name' => 'Food', - 'is_featured' => true, - ]) - ->assertCreated() - ->assertJsonPath('data.code', 'food') - ->assertJsonPath('data.category_name', 'Food') - ->assertJsonPath('data.group_name', 'Food') - ->assertJsonPath('data.is_featured', true) - ->assertJsonPath('data.type', 'category') - ->assertJsonPath('data.product_layout', 'row') - ->assertJsonPath('data.group_layout', 'paginated'); - - $categoryId = $response->json('data.category_id'); - $this->assertDatabaseHas('categorias', [ - 'id' => $categoryId, - 'tenant_code' => $tenant->codigo, - 'nombre' => 'Food', - ]); - $this->assertDatabaseHas('featured_groups', [ - 'tenant_code' => $tenant->codigo, - 'code' => 'food', - 'source_type' => 'category', - 'category_id' => $categoryId, - 'product_layout' => 'row', - 'group_layout' => 'paginated', - 'group_name' => 'Food', - ]); - } - - public function test_store_uses_column_with_cart_when_the_category_is_not_featured(): void - { - $tenant = $this->createTenant('acme'); - Sanctum::actingAs($this->createAdminAppUser($tenant)); - - $this->postJson('/api/v1/adminapp/tenant/featured-groups', [ - 'category_name' => 'Parking', - 'is_featured' => false, - ]) - ->assertCreated() - ->assertJsonPath('data.is_featured', false) - ->assertJsonPath('data.product_layout', 'column_with_cart') - ->assertJsonPath('data.group_layout', 'paginated'); - } - - public function test_update_changes_the_category_and_group_together(): void - { - $tenant = $this->createTenant('acme'); - $group = $this->createCategoryGroup($tenant, 'Old name', ProductLayout::ColumnWithCart); - Sanctum::actingAs($this->createAdminAppUser($tenant)); - - $this->putJson("/api/v1/adminapp/tenant/featured-groups/{$group->id}", [ - 'category_name' => 'New name', - 'is_featured' => true, - ]) - ->assertOk() - ->assertJsonPath('data.code', 'old-name') - ->assertJsonPath('data.category_name', 'New name') - ->assertJsonPath('data.group_name', 'New name') - ->assertJsonPath('data.is_featured', true) - ->assertJsonPath('data.product_layout', 'row') - ->assertJsonPath('data.group_layout', 'paginated'); - - $this->assertDatabaseHas('categorias', [ - 'id' => $group->category_id, - 'nombre' => 'New name', - ]); - $this->assertDatabaseHas('featured_groups', [ - 'id' => $group->id, - 'code' => 'old-name', - 'group_name' => 'New name', - 'product_layout' => 'row', - 'group_layout' => 'paginated', - ]); - } - - public function test_update_rejects_groups_from_another_tenant_or_source(): void - { - $tenant = $this->createTenant('acme'); - $otherTenant = $this->createTenant('other'); - $otherGroup = $this->createCategoryGroup($otherTenant, 'Other'); - $allGroup = FeaturedGroup::query()->create([ - 'tenant_code' => $tenant->codigo, - 'source_type' => FeaturedGroupSource::All, - 'product_layout' => ProductLayout::Row, - 'group_layout' => GroupLayout::Paginated, - 'group_name' => 'All products', - 'group_order' => 0, - ]); - Sanctum::actingAs($this->createAdminAppUser($tenant)); - - $this->putJson( - "/api/v1/adminapp/tenant/featured-groups/{$otherGroup->id}", - $this->payload(), - )->assertNotFound(); - $this->putJson( - "/api/v1/adminapp/tenant/featured-groups/{$allGroup->id}", - $this->payload(), - )->assertNotFound(); - } - - public function test_name_and_featured_flag_are_required(): void - { - $tenant = $this->createTenant('acme'); - Sanctum::actingAs($this->createAdminAppUser($tenant)); - - $this->postJson('/api/v1/adminapp/tenant/featured-groups', [ - 'category_name' => '', - 'is_featured' => 'yes', - ]) - ->assertUnprocessable() - ->assertJsonValidationErrors(['category_name', 'is_featured']); - - $this->assertDatabaseCount('categorias', 0); - $this->assertDatabaseCount('featured_groups', 0); - } - - public function test_the_controller_is_not_available_for_non_onticket_tenants(): void - { - $tenant = $this->createTenant('store', 'shopit'); - Sanctum::actingAs($this->createAdminAppUser($tenant)); - - $this->getJson('/api/v1/adminapp/tenant/featured-groups')->assertNotFound(); - $this->postJson('/api/v1/adminapp/tenant/featured-groups', $this->payload()) - ->assertNotFound(); - } - - public function test_a_customer_cannot_manage_onticket_featured_groups(): void - { - Sanctum::actingAs(User::factory()->create([ - 'rol_codigo' => RoleCode::User->value, - 'tenant_codigo' => null, - ])); - - $this->getJson('/api/v1/adminapp/tenant/featured-groups')->assertForbidden(); - $this->postJson('/api/v1/adminapp/tenant/featured-groups', $this->payload()) - ->assertForbidden(); - } - - /** @return array{category_name: string, is_featured: bool} */ - private function payload(): array - { - return [ - 'category_name' => 'Food', - 'is_featured' => true, - ]; - } - - private function createTenant(string $code, string $websiteType = 'onticket'): Tenant - { - return Tenant::query()->create([ - 'codigo' => $code, - 'nombre' => ucfirst($code), - 'dominio' => "{$code}.test", - 'website_type_code' => $websiteType, - ]); - } - - private function createAdminAppUser(Tenant $tenant): User - { - return User::factory()->create([ - 'rol_codigo' => RoleCode::AdminApp->value, - 'tenant_codigo' => $tenant->codigo, - ]); - } - - private function createCategoryGroup( - Tenant $tenant, - string $name, - ProductLayout $productLayout = ProductLayout::Row, - int $order = 0, - ): FeaturedGroup { - $category = Category::query()->create([ - 'tenant_code' => $tenant->codigo, - 'nombre' => $name, - ]); - - return FeaturedGroup::query()->create([ - 'tenant_code' => $tenant->codigo, - 'source_type' => FeaturedGroupSource::Category, - 'category_id' => $category->id, - 'product_layout' => $productLayout, - 'group_layout' => GroupLayout::Paginated, - 'group_name' => $name, - 'group_order' => $order, - ]); - } -}