From 53f760f899d36e0b68ba36b8cf649b672a8500df Mon Sep 17 00:00:00 2001 From: Matias Perrone Date: Mon, 20 Oct 2025 15:17:07 -0300 Subject: [PATCH] feat: Extend Swagger Coverage for controller `OAuth2SummitsTicketTypesApiController` --- .../OAuth2SummitsTicketTypesApiController.php | 344 +++++++++++++++++- app/Swagger/SummitRegistrationSchemas.php | 70 +++- 2 files changed, 412 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitsTicketTypesApiController.php b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitsTicketTypesApiController.php index 962d7d1b3..90bcd310a 100644 --- a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitsTicketTypesApiController.php +++ b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitsTicketTypesApiController.php @@ -15,6 +15,7 @@ use App\ModelSerializers\SerializerUtils; use App\Rules\Boolean; use App\Services\Model\ISummitTicketTypeService; +use Illuminate\Http\Response; use Illuminate\Support\Facades\Log; use models\exceptions\ValidationException; use models\oauth2\IResourceServerContext; @@ -22,6 +23,7 @@ use models\summit\ISummitTicketTypeRepository; use models\summit\SummitTicketType; use ModelSerializers\SerializerRegistry; +use OpenApi\Attributes as OA; use utils\Filter; use utils\FilterElement; use utils\PagingInfo; @@ -74,6 +76,61 @@ public function __construct * @param $summit_id * @return mixed */ + #[OA\Get( + path: "/api/v1/summits/{id}/ticket-types", + summary: "Get all ticket types for a summit (public audience only)", + security: [["Bearer" => []]], + tags: ["summit-ticket-types"], + parameters: [ + new OA\Parameter( + name: "id", + in: "path", + required: true, + schema: new OA\Schema(type: "integer"), + description: "The summit id" + ), + new OA\Parameter( + name: "page", + in: "query", + required: false, + schema: new OA\Schema(type: "integer", default: 1), + description: "Page number" + ), + new OA\Parameter( + name: "per_page", + in: "query", + required: false, + schema: new OA\Schema(type: "integer", default: 10), + description: "Items per page" + ), + new OA\Parameter( + name: "filter", + in: "query", + required: false, + explode: false, + schema: new OA\Schema(type: "string"), + description: "Filter operators: id==, badge_type_id==, name=@/@@/==, description=@/@@/==, external_id=@/@@/==, audience=@/@@/==, sales_start_date>/=/ ==/[], sales_end_date>/=/ ==/[], created>/=/ ==/[], last_edited>/=/ ==/[], allows_to_delegate==" + ), + new OA\Parameter( + name: "order", + in: "query", + required: false, + explode: false, + schema: new OA\Schema(type: "string"), + description: "Order by fields: id, created, name, external_id, audience" + ) + ], + responses: [ + new OA\Response( + response: 200, + description: "OK", + content: new OA\JsonContent(ref: "#/components/schemas/PaginatedSummitTicketTypesResponse") + ), + new OA\Response(response: Response::HTTP_UNAUTHORIZED, description: "Unauthorized"), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Not Found"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error") + ] + )] public function getAllBySummit($summit_id) { @@ -225,6 +282,61 @@ function ($page, $per_page, $filter, $order, $applyExtraFilters) use ($summit) { * @param $summit_id * @return mixed */ + #[OA\Get( + path: "/api/v2/summits/{id}/ticket-types", + summary: "Get all ticket types for a summit (all audiences)", + security: [["Bearer" => []]], + tags: ["summit-ticket-types"], + parameters: [ + new OA\Parameter( + name: "id", + in: "path", + required: true, + schema: new OA\Schema(type: "integer"), + description: "The summit id" + ), + new OA\Parameter( + name: "page", + in: "query", + required: false, + schema: new OA\Schema(type: "integer", default: 1), + description: "Page number" + ), + new OA\Parameter( + name: "per_page", + in: "query", + required: false, + schema: new OA\Schema(type: "integer", default: 10), + description: "Items per page" + ), + new OA\Parameter( + name: "filter", + in: "query", + required: false, + explode: false, + schema: new OA\Schema(type: "string"), + description: "Filter operators: id==, badge_type_id==, name=@/@@/==, description=@/@@/==, external_id=@/@@/==, audience=@/@@/==, sales_start_date>/=/ ==/[], sales_end_date>/=/ ==/[], created>/=/ ==/[], last_edited>/=/ ==/[], allows_to_delegate==" + ), + new OA\Parameter( + name: "order", + in: "query", + required: false, + explode: false, + schema: new OA\Schema(type: "string"), + description: "Order by fields: id, created, name, external_id, audience" + ) + ], + responses: [ + new OA\Response( + response: 200, + description: "OK", + content: new OA\JsonContent(ref: "#/components/schemas/PaginatedSummitTicketTypesResponse") + ), + new OA\Response(response: Response::HTTP_UNAUTHORIZED, description: "Unauthorized"), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Not Found"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error") + ] + )] public function getAllBySummitV2($summit_id) { $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id); @@ -288,6 +400,40 @@ function ($page, $per_page, $filter, $order, $applyExtraFilters) use ($summit) { * @param $summit_id * @return mixed */ + #[OA\Get( + path: "/api/v1/summits/{id}/ticket-types/allowed", + summary: "Get allowed ticket types for current member", + security: [["Bearer" => []]], + tags: ["summit-ticket-types"], + parameters: [ + new OA\Parameter( + name: "id", + in: "path", + required: true, + schema: new OA\Schema(type: "integer"), + description: "The summit id" + ), + new OA\Parameter( + name: "filter", + in: "query", + required: false, + explode: false, + schema: new OA\Schema(type: "string"), + description: "Filter operators: promo_code==" + ) + ], + responses: [ + new OA\Response( + response: 200, + description: "OK", + content: new OA\JsonContent(ref: "#/components/schemas/PaginatedSummitTicketTypesResponse") + ), + new OA\Response(response: Response::HTTP_UNAUTHORIZED, description: "Unauthorized"), + new OA\Response(response: Response::HTTP_FORBIDDEN, description: "Forbidden"), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Not Found"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error") + ] + )] public function getAllowedBySummitAndCurrentMember($summit_id) { return $this->processRequest(function () use ($summit_id) { @@ -336,6 +482,38 @@ public function getAllowedBySummitAndCurrentMember($summit_id) * @param $ticket_type_id * @return mixed */ + #[OA\Get( + path: "/api/v1/summits/{id}/ticket-types/{ticket_type_id}", + summary: "Get a specific ticket type by id", + security: [["Bearer" => []]], + tags: ["summit-ticket-types"], + parameters: [ + new OA\Parameter( + name: "id", + in: "path", + required: true, + schema: new OA\Schema(type: "integer"), + description: "The summit id" + ), + new OA\Parameter( + name: "ticket_type_id", + in: "path", + required: true, + schema: new OA\Schema(type: "integer"), + description: "The ticket type id" + ) + ], + responses: [ + new OA\Response( + response: 200, + description: "OK", + content: new OA\JsonContent(ref: "#/components/schemas/SummitTicketType") + ), + new OA\Response(response: Response::HTTP_UNAUTHORIZED, description: "Unauthorized"), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Not Found"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error") + ] + )] public function getTicketTypeBySummit($summit_id, $ticket_type_id) { return $this->processRequest(function () use ($summit_id, $ticket_type_id) { @@ -357,6 +535,41 @@ public function getTicketTypeBySummit($summit_id, $ticket_type_id) * @param $summit_id * @return mixed */ + #[OA\Post( + path: "/api/v1/summits/{id}/ticket-types", + summary: "Create a new ticket type for a summit", + security: [["Bearer" => []]], + tags: ["summit-ticket-types"], + parameters: [ + new OA\Parameter( + name: "id", + in: "path", + required: true, + schema: new OA\Schema(type: "integer"), + description: "The summit id" + ) + ], + requestBody: new OA\RequestBody( + required: true, + content: new OA\MediaType( + mediaType: "application/json", + schema: new OA\Schema(ref: "#/components/schemas/SummitTicketType") + ) + ), + responses: [ + new OA\Response( + response: 201, + description: "Created", + content: new OA\JsonContent(ref: "#/components/schemas/SummitTicketType") + ), + new OA\Response(response: Response::HTTP_BAD_REQUEST, description: "Bad Request"), + new OA\Response(response: Response::HTTP_UNAUTHORIZED, description: "Unauthorized"), + new OA\Response(response: Response::HTTP_FORBIDDEN, description: "Forbidden"), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Not Found"), + new OA\Response(response: Response::HTTP_PRECONDITION_FAILED, description: "Validation Error"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error") + ] + )] public function addTicketTypeBySummit($summit_id) { return $this->processRequest(function () use ($summit_id) { @@ -381,6 +594,48 @@ public function addTicketTypeBySummit($summit_id) * @param $ticket_type_id * @return mixed */ + #[OA\Put( + path: "/api/v1/summits/{id}/ticket-types/{ticket_type_id}", + summary: "Update a ticket type", + security: [["Bearer" => []]], + tags: ["summit-ticket-types"], + parameters: [ + new OA\Parameter( + name: "id", + in: "path", + required: true, + schema: new OA\Schema(type: "integer"), + description: "The summit id" + ), + new OA\Parameter( + name: "ticket_type_id", + in: "path", + required: true, + schema: new OA\Schema(type: "integer"), + description: "The ticket type id" + ) + ], + requestBody: new OA\RequestBody( + required: true, + content: new OA\MediaType( + mediaType: "application/json", + schema: new OA\Schema(ref: "#/components/schemas/SummitTicketType") + ) + ), + responses: [ + new OA\Response( + response: 200, + description: "OK", + content: new OA\JsonContent(ref: "#/components/schemas/SummitTicketType") + ), + new OA\Response(response: Response::HTTP_BAD_REQUEST, description: "Bad Request"), + new OA\Response(response: Response::HTTP_UNAUTHORIZED, description: "Unauthorized"), + new OA\Response(response: Response::HTTP_FORBIDDEN, description: "Forbidden"), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Not Found"), + new OA\Response(response: Response::HTTP_PRECONDITION_FAILED, description: "Validation Error"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error") + ] + )] public function updateTicketTypeBySummit($summit_id, $ticket_type_id) { return $this->processRequest(function () use ($summit_id, $ticket_type_id) { @@ -405,6 +660,35 @@ public function updateTicketTypeBySummit($summit_id, $ticket_type_id) * @param $ticket_type_id * @return mixed */ + #[OA\Delete( + path: "/api/v1/summits/{id}/ticket-types/{ticket_type_id}", + summary: "Delete a ticket type", + security: [["Bearer" => []]], + tags: ["summit-ticket-types"], + parameters: [ + new OA\Parameter( + name: "id", + in: "path", + required: true, + schema: new OA\Schema(type: "integer"), + description: "The summit id" + ), + new OA\Parameter( + name: "ticket_type_id", + in: "path", + required: true, + schema: new OA\Schema(type: "integer"), + description: "The ticket type id" + ) + ], + responses: [ + new OA\Response(response: 204, description: "No Content"), + new OA\Response(response: Response::HTTP_UNAUTHORIZED, description: "Unauthorized"), + new OA\Response(response: Response::HTTP_FORBIDDEN, description: "Forbidden"), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Not Found"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error") + ] + )] public function deleteTicketTypeBySummit($summit_id, $ticket_type_id) { return $this->processRequest(function () use ($summit_id, $ticket_type_id) { @@ -422,6 +706,33 @@ public function deleteTicketTypeBySummit($summit_id, $ticket_type_id) * @param $summit_id * @return mixed */ + #[OA\Post( + path: "/api/v1/summits/{id}/ticket-types/seed-defaults", + summary: "Seed default ticket types from Eventbrite", + security: [["Bearer" => []]], + tags: ["summit-ticket-types"], + parameters: [ + new OA\Parameter( + name: "id", + in: "path", + required: true, + schema: new OA\Schema(type: "integer"), + description: "The summit id" + ) + ], + responses: [ + new OA\Response( + response: 201, + description: "Created", + content: new OA\JsonContent(ref: "#/components/schemas/PaginatedSummitTicketTypesResponse") + ), + new OA\Response(response: Response::HTTP_BAD_REQUEST, description: "Bad Request"), + new OA\Response(response: Response::HTTP_UNAUTHORIZED, description: "Unauthorized"), + new OA\Response(response: Response::HTTP_FORBIDDEN, description: "Forbidden"), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Not Found"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error") + ] + )] public function seedDefaultTicketTypesBySummit($summit_id) { return $this->processRequest(function () use ($summit_id) { @@ -453,6 +764,37 @@ public function seedDefaultTicketTypesBySummit($summit_id) * @param $currency_symbol * @return mixed */ + #[OA\Put( + path: "/api/v1/summits/{id}/ticket-types/all/currency/{currency_symbol}", + summary: "Update currency symbol for all ticket types in a summit", + security: [["Bearer" => []]], + tags: ["summit-ticket-types"], + parameters: [ + new OA\Parameter( + name: "id", + in: "path", + required: true, + schema: new OA\Schema(type: "integer"), + description: "The summit id" + ), + new OA\Parameter( + name: "currency_symbol", + in: "path", + required: true, + schema: new OA\Schema(type: "string"), + description: "The currency symbol (e.g., USD, EUR)" + ) + ], + responses: [ + new OA\Response(response: 200, description: "OK"), + new OA\Response(response: Response::HTTP_BAD_REQUEST, description: "Bad Request"), + new OA\Response(response: Response::HTTP_UNAUTHORIZED, description: "Unauthorized"), + new OA\Response(response: Response::HTTP_FORBIDDEN, description: "Forbidden"), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Not Found"), + new OA\Response(response: Response::HTTP_PRECONDITION_FAILED, description: "Validation Error"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error") + ] + )] public function updateCurrencySymbol($summit_id, $currency_symbol) { return $this->processRequest(function () use ($summit_id, $currency_symbol) { @@ -477,4 +819,4 @@ public function updateCurrencySymbol($summit_id, $currency_symbol) return $this->updated(); }); } -} \ No newline at end of file +} diff --git a/app/Swagger/SummitRegistrationSchemas.php b/app/Swagger/SummitRegistrationSchemas.php index 6b3e2f895..8bb5e54ba 100644 --- a/app/Swagger/SummitRegistrationSchemas.php +++ b/app/Swagger/SummitRegistrationSchemas.php @@ -2,6 +2,74 @@ namespace App\Swagger\schemas; +use models\summit\SummitTicketType; use OpenApi\Attributes as OA; -// + +#[OA\Schema( + schema: "SummitTicketType", + required: [ + "id", + "name", + "description", + "external_id", + "summit_id", + "cost", + "currency", + "currency_symbol", + "quantity_2_sell", + "max_quantity_per_order", + "sales_start_date", + "sales_end_date", + "badge_type_id", + "quantity_sold", + "audience", + "allows_to_delegate", + "allows_to_reassign", + "sub_type", + ], + properties: [ + new OA\Property(property: "id", type: "integer"), + new OA\Property(property: "name", type: "string"), + new OA\Property(property: "description", type: "string"), + new OA\Property(property: "external_id", type: "string"), + new OA\Property(property: "summit_id", type: "integer"), + new OA\Property(property: "cost", type: "number", format: "float"), + new OA\Property(property: "currency", type: "string"), + new OA\Property(property: "currency_symbol", type: "string"), + new OA\Property(property: "quantity_2_sell", type: "integer"), + new OA\Property(property: "max_quantity_per_order", type: "integer"), + new OA\Property(property: "sales_start_date", type: "integer", description: "Unix timestamp"), + new OA\Property(property: "sales_end_date", type: "integer", description: "Unix timestamp"), + new OA\Property(property: "badge_type_id", type: "integer"), + new OA\Property(property: "quantity_sold", type: "integer"), + new OA\Property(property: "audience", type: "string", enum: SummitTicketType::AllowedAudience), + new OA\Property(property: "allows_to_delegate", type: "boolean"), + new OA\Property(property: "allows_to_reassign", type: "boolean"), + new OA\Property(property: "applied_taxes", type: ["integer", "SummitTaxType"]), + new OA\Property(property: "sub_type", type: "string", enum: SummitTicketType::AllowedSubTypes), + ] +)] +class SummitTicketTypeSchema +{ +} + +#[OA\Schema( + schema: "PaginatedSummitTicketTypesResponse", + allOf: [ + new OA\Schema(ref: "#/components/schemas/PaginateDataSchemaResponse"), + new OA\Schema( + type: "object", + properties: [ + new OA\Property( + property: "data", + type: "array", + items: new OA\Items(ref: "#/components/schemas/SummitTicketType") + ) + ] + ) + ] +)] +class PaginatedSummitTicketTypesResponse +{ +}