""" Company endpoints for API v1. Provides CRUD operations for Company entities with filtering and search. """ from typing import List, Optional from uuid import UUID from django.shortcuts import get_object_or_404 from django.db.models import Q from ninja import Router, Query from ninja.pagination import paginate, PageNumberPagination from apps.entities.models import Company from ..schemas import ( CompanyCreate, CompanyUpdate, CompanyOut, CompanyListOut, ErrorResponse ) router = Router(tags=["Companies"]) class CompanyPagination(PageNumberPagination): """Custom pagination for companies.""" page_size = 50 @router.get( "/", response={200: List[CompanyOut]}, summary="List companies", description="Get a paginated list of companies with optional filtering" ) @paginate(CompanyPagination) def list_companies( request, search: Optional[str] = Query(None, description="Search by company name"), company_type: Optional[str] = Query(None, description="Filter by company type"), location_id: Optional[UUID] = Query(None, description="Filter by location"), ordering: Optional[str] = Query("-created", description="Sort by field (prefix with - for descending)") ): """ List all companies with optional filters. **Filters:** - search: Search company names (case-insensitive partial match) - company_type: Filter by specific company type - location_id: Filter by headquarters location - ordering: Sort results (default: -created) **Returns:** Paginated list of companies """ queryset = Company.objects.all() # Apply search filter if search: queryset = queryset.filter( Q(name__icontains=search) | Q(description__icontains=search) ) # Apply company type filter if company_type: queryset = queryset.filter(company_types__contains=[company_type]) # Apply location filter if location_id: queryset = queryset.filter(location_id=location_id) # Apply ordering valid_order_fields = ['name', 'created', 'modified', 'founded_date', 'park_count', 'ride_count'] order_field = ordering.lstrip('-') if order_field in valid_order_fields: queryset = queryset.order_by(ordering) else: queryset = queryset.order_by('-created') return queryset @router.get( "/{company_id}", response={200: CompanyOut, 404: ErrorResponse}, summary="Get company", description="Retrieve a single company by ID" ) def get_company(request, company_id: UUID): """ Get a company by ID. **Parameters:** - company_id: UUID of the company **Returns:** Company details """ company = get_object_or_404(Company, id=company_id) return company @router.post( "/", response={201: CompanyOut, 400: ErrorResponse}, summary="Create company", description="Create a new company (requires authentication)" ) def create_company(request, payload: CompanyCreate): """ Create a new company. **Authentication:** Required **Parameters:** - payload: Company data **Returns:** Created company """ # TODO: Add authentication check # if not request.auth: # return 401, {"detail": "Authentication required"} company = Company.objects.create(**payload.dict()) return 201, company @router.put( "/{company_id}", response={200: CompanyOut, 404: ErrorResponse, 400: ErrorResponse}, summary="Update company", description="Update an existing company (requires authentication)" ) def update_company(request, company_id: UUID, payload: CompanyUpdate): """ Update a company. **Authentication:** Required **Parameters:** - company_id: UUID of the company - payload: Updated company data **Returns:** Updated company """ # TODO: Add authentication check # if not request.auth: # return 401, {"detail": "Authentication required"} company = get_object_or_404(Company, id=company_id) # Update only provided fields for key, value in payload.dict(exclude_unset=True).items(): setattr(company, key, value) company.save() return company @router.patch( "/{company_id}", response={200: CompanyOut, 404: ErrorResponse, 400: ErrorResponse}, summary="Partial update company", description="Partially update an existing company (requires authentication)" ) def partial_update_company(request, company_id: UUID, payload: CompanyUpdate): """ Partially update a company. **Authentication:** Required **Parameters:** - company_id: UUID of the company - payload: Fields to update **Returns:** Updated company """ # TODO: Add authentication check # if not request.auth: # return 401, {"detail": "Authentication required"} company = get_object_or_404(Company, id=company_id) # Update only provided fields for key, value in payload.dict(exclude_unset=True).items(): setattr(company, key, value) company.save() return company @router.delete( "/{company_id}", response={204: None, 404: ErrorResponse}, summary="Delete company", description="Delete a company (requires authentication)" ) def delete_company(request, company_id: UUID): """ Delete a company. **Authentication:** Required **Parameters:** - company_id: UUID of the company **Returns:** No content (204) """ # TODO: Add authentication check # if not request.auth: # return 401, {"detail": "Authentication required"} company = get_object_or_404(Company, id=company_id) company.delete() return 204, None @router.get( "/{company_id}/parks", response={200: List[dict], 404: ErrorResponse}, summary="Get company parks", description="Get all parks operated by a company" ) def get_company_parks(request, company_id: UUID): """ Get parks operated by a company. **Parameters:** - company_id: UUID of the company **Returns:** List of parks """ company = get_object_or_404(Company, id=company_id) parks = company.operated_parks.all().values('id', 'name', 'slug', 'status', 'park_type') return list(parks) @router.get( "/{company_id}/rides", response={200: List[dict], 404: ErrorResponse}, summary="Get company rides", description="Get all rides manufactured by a company" ) def get_company_rides(request, company_id: UUID): """ Get rides manufactured by a company. **Parameters:** - company_id: UUID of the company **Returns:** List of rides """ company = get_object_or_404(Company, id=company_id) rides = company.manufactured_rides.all().values('id', 'name', 'slug', 'status', 'ride_category') return list(rides)