from typing import List, Optional from fastapi import APIRouter, Depends, HTTPException, status, Request from sqlalchemy.orm import Session from datetime import date from app.api.deps import get_db, get_current_read_user, get_current_operator_user from app.crud.crud_arrival import arrival as crud_arrival from app.schemas.arrival import Arrival, ArrivalCreate, ArrivalUpdate, ArrivalStatus, ArrivalStatusUpdate from app.models.ppr import User from app.core.utils import get_client_ip router = APIRouter() @router.get("/", response_model=List[Arrival]) async def get_arrivals( request: Request, skip: int = 0, limit: int = 100, status: Optional[ArrivalStatus] = None, date_from: Optional[date] = None, date_to: Optional[date] = None, db: Session = Depends(get_db), current_user: User = Depends(get_current_read_user) ): """Get arrival records with optional filtering""" arrivals = crud_arrival.get_multi( db, skip=skip, limit=limit, status=status, date_from=date_from, date_to=date_to ) return arrivals @router.post("/", response_model=Arrival) async def create_arrival( request: Request, arrival_in: ArrivalCreate, db: Session = Depends(get_db), current_user: User = Depends(get_current_operator_user) ): """Create a new arrival record""" arrival = crud_arrival.create(db, obj_in=arrival_in, created_by=current_user.username) # Send real-time update via WebSocket if hasattr(request.app.state, 'connection_manager'): await request.app.state.connection_manager.broadcast({ "type": "arrival_booked_in", "data": { "id": arrival.id, "registration": arrival.registration, "in_from": arrival.in_from, "status": arrival.status.value } }) return arrival @router.get("/{arrival_id}", response_model=Arrival) async def get_arrival( arrival_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_read_user) ): """Get a specific arrival record""" arrival = crud_arrival.get(db, arrival_id=arrival_id) if not arrival: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Arrival record not found" ) return arrival @router.put("/{arrival_id}", response_model=Arrival) async def update_arrival( request: Request, arrival_id: int, arrival_in: ArrivalUpdate, db: Session = Depends(get_db), current_user: User = Depends(get_current_operator_user) ): """Update an arrival record""" db_arrival = crud_arrival.get(db, arrival_id=arrival_id) if not db_arrival: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Arrival record not found" ) # Get user IP from request user_ip = request.client.host if request.client else None arrival = crud_arrival.update( db, db_obj=db_arrival, obj_in=arrival_in, user=current_user.username, user_ip=user_ip ) # Send real-time update if hasattr(request.app.state, 'connection_manager'): await request.app.state.connection_manager.broadcast({ "type": "arrival_updated", "data": { "id": arrival.id, "registration": arrival.registration, "status": arrival.status.value } }) return arrival @router.patch("/{arrival_id}/status", response_model=Arrival) async def update_arrival_status( request: Request, arrival_id: int, status_update: ArrivalStatusUpdate, db: Session = Depends(get_db), current_user: User = Depends(get_current_operator_user) ): """Update arrival status""" client_ip = get_client_ip(request) arrival = crud_arrival.update_status( db, arrival_id=arrival_id, status=status_update.status, timestamp=status_update.timestamp, user=current_user.username, user_ip=client_ip ) if not arrival: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Arrival record not found" ) # Send real-time update if hasattr(request.app.state, 'connection_manager'): await request.app.state.connection_manager.broadcast({ "type": "arrival_status_update", "data": { "id": arrival.id, "registration": arrival.registration, "status": arrival.status.value, "landed_dt": arrival.landed_dt.isoformat() if arrival.landed_dt else None } }) return arrival @router.delete("/{arrival_id}", response_model=Arrival) async def cancel_arrival( request: Request, arrival_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_operator_user) ): """Cancel an arrival record""" arrival = crud_arrival.cancel(db, arrival_id=arrival_id) if not arrival: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Arrival record not found" ) # Send real-time update if hasattr(request.app.state, 'connection_manager'): await request.app.state.connection_manager.broadcast({ "type": "arrival_cancelled", "data": { "id": arrival.id, "registration": arrival.registration } }) return arrival