from datetime import datetime from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.orm import selectinload from .enums import UserEventStatus from .models import Event, User, UserEvent async def get_user_by_tg_id(session: AsyncSession, user_tg_id: int) -> User | None: result = await session.execute( select(User).options(selectinload(User.events)).where(User.tg_id == user_tg_id) ) return result.scalar_one_or_none() async def create_user( session: AsyncSession, tg_id: int, fullname: str, phone: str = "", role: str = "user", ) -> User: user = User(tg_id=tg_id, fullname=fullname, role=role, phone=phone) session.add(user) await session.commit() await session.refresh(user) return user async def update_user( session: AsyncSession, tg_id: int, fullname: str = "", phone: str = "" ) -> None: user = await get_user_by_tg_id(session, tg_id) if fullname: user.fullname = fullname if phone: user.phone = phone await session.commit() return user async def get_events_list(session: AsyncSession) -> list[Event]: result = await session.execute( select(Event).where(Event.start_date >= datetime.now()) ) return result.scalars() async def get_event_by_id(session: AsyncSession, event_id: int) -> Event: result = await session.execute(select(Event).where(Event.id == event_id)) return result.scalar_one_or_none() async def create_event( session: AsyncSession, title: str, description: str, start_date: datetime, end_date: datetime, ) -> Event: event = Event( title=title, description=description, start_date=start_date, end_date=end_date, ) session.add(event) await session.commit() await session.refresh(event) return event async def delete_event( session: AsyncSession, event_id: int, ) -> None: session.delete(await get_event_by_id(session, event_id)) await session.commit() async def update_event( session: AsyncSession, event_id: int, title: str = None, description: str = None, start_date: datetime = None, end_date: datetime = None, ) -> Event: event = await get_event_by_id(session, event_id) if title: event.title = title if description: event.description = description if start_date: event.start_date = start_date if end_date: event.end_date = end_date await session.commit() return event async def register_user_to_event(session: AsyncSession, user_id: int, event_id: int): user_event = ( await session.execute( select(UserEvent).where( (UserEvent.user_id == user_id) & (UserEvent.event_id == event_id) ) ) ).scalar_one_or_none() if user_event is None: user_event = UserEvent(user_id=user_id, event_id=event_id) session.add(user_event) await session.flush() if user_event.status == UserEventStatus.CANCELLED.value: user_event.status = UserEventStatus.NOT_CONFIRMED.value await session.commit() async def unregister_user_to_event(session: AsyncSession, user_id: int, event_id: int): user_event = ( await session.execute( select(UserEvent).where( (UserEvent.user_id == user_id) & (UserEvent.event_id == event_id) ) ) ).scalar_one() user_event.status = UserEventStatus.CANCELLED.value await session.commit()