from fastapi import APIRouter, HTTPException, Query from uuid import uuid4 from datetime import datetime, date from typing import Optional from pydantic import BaseModel from ..models.flight_models import ( BookingRequest, RefundRequest, RescheduleRequest ) from ..data.flight_dummy_data import ( flight_db, booking_db, refund_db ) router = APIRouter(prefix="/flights", tags=["Flights"]) book_id_counter = 1 refund_id_counter = 1 # ====================== # helper # ====================== def find_flight(flight_id): for f in flight_db: if f["flight_id"] == flight_id: return f return None def find_booking(booking_id): for b in booking_db: if b["booking_id"] == booking_id: return b return None # ====================== # GET all flights # ====================== @router.get("/") def get_all_flights(): return flight_db @router.get("/search") def search_flights( departure_date: Optional[str] = Query(None), origin: Optional[str] = Query(None), destination: Optional[str] = Query(None), seat_class: Optional[str] = Query(None), flight_id: Optional[str] = Query(None), ): results = [] for flight in flight_db: if departure_date: departure_date_2 = datetime.strptime(departure_date, "%Y-%m-%d") if flight["departure_time"].date() != departure_date_2.date(): continue if origin: if flight["origin"].upper() != origin.upper(): continue if destination: if flight["destination"].upper() != destination.upper(): continue if seat_class: if flight["seat_class"].upper() != destination.upper(): continue if flight_id: if flight["flight_id"] != flight_id: continue results.append(flight) # stop at top 15 if len(results) == 15: break return { "total": len(results), "limit": 15, "filters": { "departure_date": departure_date, "origin": origin, "destination": destination }, "flights": results } # ====================== # GET flight by id # ====================== @router.get("/{flight_id}") def get_flight(flight_id: str): flight = find_flight(flight_id) if not flight: return dict(status=404, messages="Flight not found") return flight # ====================== # BOOKING # ====================== @router.post("/booking") def create_booking(data: BookingRequest): global book_id_counter flight = find_flight(data.flight_id) if not flight: return dict(status=404, messages="Flight not found") booking = { "booking_id": f"BK{book_id_counter:04d}", "customer_name": data.customer_name, "customer_id": data.customer_id, "flight_id": flight["flight_id"], "price_paid": flight["price"], "status": "pending", "booked_at": datetime.now() } booking_db.append(booking) book_id_counter += 1 return booking # ====================== # GET BOOKING # ====================== @router.get("/booking/search") def get_booking(booking_id: Optional[str] = Query(None)): booking = find_booking(booking_id) if not booking: return dict(status=404, messages="Booking not found") return booking # ====================== # BOOKING PAYMENT # ====================== class BookingPaymentRequest(BaseModel): booking_id: str payment_method: str payment_amount: float # ====================== # REFUND PAYMENT # ====================== class RefundPaymentRequest(BaseModel): refund_id: str bank_account: str @router.post("/booking/payment") def booking_payment(data: BookingPaymentRequest): booking = find_booking(data.booking_id) if not booking: raise HTTPException(404, "Booking not found") if booking["status"] == "complete": raise HTTPException(400, "Booking already paid at " + booking["paid_at"].strftime("%d-%m-%Y %H:%M")) if booking["price_paid"] != data.payment_amount: raise HTTPException(400, "Payment amount is incorrect") booking["status"] = "complete" booking["payment_method"] = data.payment_method booking["paid_at"] = datetime.now() return { "message": "Booking payment successful", "booking": booking } @router.post("/refund/payment") def refund_payment(data: RefundPaymentRequest): refund = find_refund(data.refund_id) if not refund: raise HTTPException(404, "Refund not found") if refund["status"] == "complete": raise HTTPException(400, "Refund already completed") refund["status"] = "complete" refund["bank_account"] = data.bank_account refund["processed_at"] = datetime.now() return { "message": "Refund completed", "refund": refund } # ====================== # REFUND # 80% refund # ====================== @router.post("/refund") def refund(data: RefundRequest): global refund_id_counter booking = find_booking(data.booking_id) if not booking: # return dict(404, "Booking not found") return { "status":404, "messages":"Booking not found!" } for r in refund_db: if str(r["booking_id"]) == data.booking_id: return { "status":401, "messages":"Refund On-Process" } refund_amount = booking["price_paid"] #* 0.8 item = { # "refund_id": str(uuid4()), "refund_id": f"RF{refund_id_counter:04d}", "booking_id": booking["booking_id"], "refund_amount": refund_amount, "status": "pending" } refund_db.append(item) refund_id_counter += 1 return item # ====================== # RESCHEDULE # ====================== @router.post("/reschedule") def reschedule(data: RescheduleRequest): booking = find_booking(data.booking_id) if not booking: return dict(status=404, messages="Booking not found") new_flight = find_flight(data.new_flight_id) if not new_flight: return dict(status=404, messages="New flight not found") old_price = booking["price_paid"] new_price = new_flight["price"] diff = new_price - old_price booking["flight_id"] = new_flight["flight_id"] booking["price_paid"] = new_price if diff > 0: booking["status"] = "pending" elif diff < 0: booking["status"] = "refund-on-process" else: booking["status"] = "complete" return { "message": "Rescheduled successfully", "old_price": old_price, "new_price": new_price, "price_difference": diff }