183 lines
6.3 KiB
Python
183 lines
6.3 KiB
Python
from fastapi import APIRouter, Depends, Query, HTTPException, UploadFile, File, Form
|
|
from sqlmodel import Session, select
|
|
from typing import Optional, List
|
|
import os
|
|
import shutil
|
|
from uuid import uuid4, UUID
|
|
from app.core.database import get_session
|
|
from app.models.shuttle import Shuttle
|
|
from app.api.deps import get_current_admin
|
|
|
|
router = APIRouter(prefix="/api/shuttles", tags=["shuttles"])
|
|
|
|
UPLOAD_DIR = "uploads"
|
|
|
|
@router.get("", response_model=List[Shuttle])
|
|
async def get_shuttles(
|
|
origin: Optional[str] = Query(None),
|
|
destination: Optional[str] = Query(None),
|
|
company_name: Optional[str] = Query(None),
|
|
trip_type: Optional[str] = Query(None),
|
|
is_active: Optional[bool] = Query(None),
|
|
session: Session = Depends(get_session)
|
|
):
|
|
"""Get all shuttles with optional filters."""
|
|
statement = select(Shuttle)
|
|
|
|
if is_active is not None:
|
|
statement = statement.where(Shuttle.is_active == is_active)
|
|
|
|
if origin:
|
|
statement = statement.where(Shuttle.origin.contains(origin))
|
|
if destination:
|
|
statement = statement.where(Shuttle.destination.contains(destination))
|
|
if company_name:
|
|
statement = statement.where(Shuttle.company_name.contains(company_name))
|
|
if trip_type:
|
|
statement = statement.where(Shuttle.trip_type == trip_type)
|
|
|
|
shuttles = session.exec(statement).all()
|
|
return shuttles
|
|
|
|
@router.post("", response_model=Shuttle)
|
|
async def create_shuttle(
|
|
route_name: str = Form(...),
|
|
origin: str = Form(...),
|
|
destination: str = Form(...),
|
|
vehicle_type: str = Form(...),
|
|
company_name: Optional[str] = Form(None),
|
|
trip_type: str = Form("one_way"),
|
|
price_per_person: Optional[float] = Form(None),
|
|
price_private_trip: Optional[float] = Form(None),
|
|
estimated_duration: str = Form(...),
|
|
contact_whatsapp: str = Form(...),
|
|
phone_number: Optional[str] = Form(None),
|
|
english_speaking: bool = Form(False),
|
|
description: Optional[str] = Form(None),
|
|
departure_times: Optional[str] = Form(None),
|
|
is_active: bool = Form(True),
|
|
image: Optional[UploadFile] = File(None),
|
|
session: Session = Depends(get_session),
|
|
_: bool = Depends(get_current_admin)
|
|
):
|
|
"""Create a new shuttle trip (Admin only)."""
|
|
image_url = None
|
|
if image:
|
|
ext = os.path.splitext(image.filename)[1]
|
|
filename = f"{uuid4()}{ext}"
|
|
path = os.path.join(UPLOAD_DIR, "vehicles", filename)
|
|
with open(path, "wb") as buffer:
|
|
shutil.copyfileobj(image.file, buffer)
|
|
image_url = f"/uploads/vehicles/{filename}"
|
|
|
|
shuttle = Shuttle(
|
|
route_name=route_name,
|
|
origin=origin,
|
|
destination=destination,
|
|
vehicle_type=vehicle_type,
|
|
company_name=company_name,
|
|
trip_type=trip_type,
|
|
price_per_person=price_per_person,
|
|
price_private_trip=price_private_trip,
|
|
estimated_duration=estimated_duration,
|
|
contact_whatsapp=contact_whatsapp,
|
|
phone_number=phone_number,
|
|
english_speaking=english_speaking,
|
|
description=description,
|
|
departure_times=departure_times,
|
|
image_url=image_url,
|
|
is_active=is_active
|
|
)
|
|
session.add(shuttle)
|
|
session.commit()
|
|
session.refresh(shuttle)
|
|
return shuttle
|
|
|
|
@router.put("/{shuttle_id}", response_model=Shuttle)
|
|
async def update_shuttle(
|
|
shuttle_id: UUID,
|
|
route_name: str = Form(...),
|
|
origin: str = Form(...),
|
|
destination: str = Form(...),
|
|
vehicle_type: str = Form(...),
|
|
company_name: Optional[str] = Form(None),
|
|
trip_type: str = Form("one_way"),
|
|
price_per_person: Optional[float] = Form(None),
|
|
price_private_trip: Optional[float] = Form(None),
|
|
estimated_duration: str = Form(...),
|
|
contact_whatsapp: str = Form(...),
|
|
phone_number: Optional[str] = Form(None),
|
|
english_speaking: bool = Form(False),
|
|
description: Optional[str] = Form(None),
|
|
departure_times: Optional[str] = Form(None),
|
|
is_active: bool = Form(True),
|
|
image: Optional[UploadFile] = File(None),
|
|
session: Session = Depends(get_session),
|
|
_: bool = Depends(get_current_admin)
|
|
):
|
|
"""Update a shuttle trip (Admin only)."""
|
|
db_shuttle = session.get(Shuttle, shuttle_id)
|
|
if not db_shuttle:
|
|
raise HTTPException(status_code=404, detail="Shuttle not found")
|
|
|
|
db_shuttle.route_name = route_name
|
|
db_shuttle.origin = origin
|
|
db_shuttle.destination = destination
|
|
db_shuttle.vehicle_type = vehicle_type
|
|
db_shuttle.company_name = company_name
|
|
db_shuttle.trip_type = trip_type
|
|
db_shuttle.price_per_person = price_per_person
|
|
db_shuttle.price_private_trip = price_private_trip
|
|
db_shuttle.estimated_duration = estimated_duration
|
|
db_shuttle.contact_whatsapp = contact_whatsapp
|
|
db_shuttle.phone_number = phone_number
|
|
db_shuttle.english_speaking = english_speaking
|
|
db_shuttle.description = description
|
|
db_shuttle.departure_times = departure_times
|
|
db_shuttle.is_active = is_active
|
|
|
|
if image:
|
|
ext = os.path.splitext(image.filename)[1]
|
|
filename = f"{uuid4()}{ext}"
|
|
path = os.path.join(UPLOAD_DIR, "vehicles", filename)
|
|
with open(path, "wb") as buffer:
|
|
shutil.copyfileobj(image.file, buffer)
|
|
db_shuttle.image_url = f"/uploads/vehicles/{filename}"
|
|
|
|
session.add(db_shuttle)
|
|
session.commit()
|
|
session.refresh(db_shuttle)
|
|
return db_shuttle
|
|
|
|
@router.delete("/{shuttle_id}")
|
|
async def delete_shuttle(
|
|
shuttle_id: UUID,
|
|
session: Session = Depends(get_session),
|
|
_: bool = Depends(get_current_admin)
|
|
):
|
|
"""Delete a shuttle trip (Admin only)."""
|
|
db_shuttle = session.get(Shuttle, shuttle_id)
|
|
if not db_shuttle:
|
|
raise HTTPException(status_code=404, detail="Shuttle not found")
|
|
session.delete(db_shuttle)
|
|
session.commit()
|
|
return {"ok": True}
|
|
|
|
@router.patch("/{shuttle_id}/status")
|
|
async def update_shuttle_status(
|
|
shuttle_id: UUID,
|
|
is_active: bool = Query(...),
|
|
session: Session = Depends(get_session),
|
|
_: bool = Depends(get_current_admin)
|
|
):
|
|
"""Update shuttle active status (Admin only)."""
|
|
db_shuttle = session.get(Shuttle, shuttle_id)
|
|
if not db_shuttle:
|
|
raise HTTPException(status_code=404, detail="Shuttle not found")
|
|
|
|
db_shuttle.is_active = is_active
|
|
session.add(db_shuttle)
|
|
session.commit()
|
|
session.refresh(db_shuttle)
|
|
return db_shuttle
|