102 lines
No EOL
3.2 KiB
Python
102 lines
No EOL
3.2 KiB
Python
import re
|
|
from uuid import UUID, uuid4
|
|
from fastapi import APIRouter, Depends
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from schemas import TripCreate, TripItemOut, TripOut
|
|
from models import Item, Trip, TripItem
|
|
from database import get_db
|
|
from sqlalchemy import select
|
|
from sqlalchemy.orm import selectinload
|
|
from config import FIXED_USER_ID
|
|
|
|
router = APIRouter(prefix="/trips", tags=["Trips"])
|
|
|
|
@router.post("/", response_model=TripOut)
|
|
async def create_trip(trip: TripCreate, db: AsyncSession = Depends(get_db)):
|
|
user_id = FIXED_USER_ID
|
|
|
|
db_trip = Trip(
|
|
id=uuid4(),
|
|
name=trip.name,
|
|
user_id=user_id,
|
|
start_date=trip.start_date,
|
|
end_date=trip.end_date,
|
|
selected_tags=trip.selected_tags,
|
|
marked_tags=trip.marked_tags
|
|
)
|
|
|
|
await db.commit() # damit ID vorhanden ist
|
|
db.add(db_trip)
|
|
|
|
# Tage berechnen
|
|
days = (trip.end_date - trip.start_date).days + 1
|
|
nights = days - 1
|
|
|
|
# relevante Items
|
|
result = await db.execute(select(Item).where(Item.user_id == user_id).options(selectinload(Item.tags)))
|
|
all_items = result.scalars().all()
|
|
|
|
trip_items = []
|
|
|
|
for item in all_items:
|
|
item_tag_names = [tag.name for tag in item.tags]
|
|
|
|
if not set(item_tag_names).issubset(set(trip.selected_tags)):
|
|
continue
|
|
|
|
item_text = replace_placeholders(item.name, days, nights)
|
|
|
|
# markierte Tags matchen?
|
|
matching_marked = set(item_tag_names) & set(trip.marked_tags)
|
|
|
|
if matching_marked:
|
|
for tag in matching_marked:
|
|
trip_items.append(TripItem(
|
|
id=uuid4(),
|
|
trip_id=db_trip.id,
|
|
item_id=item.id,
|
|
tag=tag,
|
|
name=item.name,
|
|
calculated_label=item_text,
|
|
checked=False
|
|
))
|
|
else:
|
|
trip_items.append(TripItem(
|
|
id=uuid4(),
|
|
trip_id=db_trip.id,
|
|
item_id=item.id,
|
|
tag=None,
|
|
name=item.name,
|
|
calculated_label=item_text,
|
|
checked=False
|
|
))
|
|
|
|
db.add_all(trip_items)
|
|
await db.commit()
|
|
# return {"status": "trip created", "trip_id": str(db_trip.id)}
|
|
return db_trip
|
|
|
|
|
|
@router.get("/{trip_id}/items", response_model=list[TripItemOut])
|
|
async def get_trip_items(trip_id: UUID, db: AsyncSession = Depends(get_db)):
|
|
result = await db.execute(select(TripItem).where(TripItem.trip_id == trip_id).options(selectinload(TripItem.item)))
|
|
items = result.scalars().all()
|
|
return [TripItemOut.model_validate(item) for item in items]
|
|
|
|
@router.get("/", response_model=list[TripOut])
|
|
async def get_trips(db: AsyncSession = Depends(get_db)):
|
|
user_id = FIXED_USER_ID
|
|
result = await db.execute(select(Trip).where(Trip.user_id == user_id))
|
|
trips = result.scalars().all()
|
|
return trips
|
|
|
|
def replace_placeholders(text: str, days: int, nights: int) -> str:
|
|
def replacer(match):
|
|
expr = match.group(1)
|
|
expr = expr.replace("days", str(days)).replace("nights", str(nights))
|
|
try:
|
|
return str(eval(expr))
|
|
except:
|
|
return match.group(0)
|
|
|
|
return re.sub(r"{(.*?)}", replacer, text) |