···5566if TYPE_CHECKING:
77 from kefi.models.kudos.models import Action
88+ from kefi.models.plazas.models import Attendance, Plaza
899101011class User(SQLModel, table=True):
···2829 sa_relationship_kwargs=dict(foreign_keys="[Transaction.receiver_id]"),
2930 )
3031 is_admin: bool = False
3232+ attendances: list["Attendance"] = Relationship(back_populates="user")
31333234 def get_short_name(self):
3335 """Gets the short name of the user."""
···5153 # Action, the reference of the action used to send the transaction
5254 action_id: int | None = Field(default=None, foreign_key="action.id")
5355 action: Optional["Action"] = Relationship(back_populates="transactions")
5656+5757+ # Attendance, the reference of the attendance used to send the transaction
5858+ attendance_id: int | None = Field(default=None, foreign_key="attendance.id")
5959+ attendance: Optional["Attendance"] = Relationship(back_populates="transactions")
54605561 # Sender user, if not defined, is a system transaction
5662 sender_id: int | None = Field(default=None, foreign_key="user.id")
···11-import datetime
22-from typing import TYPE_CHECKING, Optional
33-44-from sqlalchemy import Column, String
55-from sqlmodel import Field, Relationship, SQLModel
66-77-if TYPE_CHECKING:
88- from kefi.models.core.models import User
99- from kefi.models.kudos.models import Action
1010-1111-1212-class MeetingSession(SQLModel, table=True):
1313- """A meeting session that represents a moment scheduled to create a group call with
1414- the different groups of attendees."""
1515-1616- date = datetime.datetime # When the meetings are going to be created
1717-1818-1919-class Attendance(SQLModel, table=True):
2020- """An attendance is a user who has spent kefis to be part of a meetings session."""
2121-2222- # Meeting session that the attendance makes reference
2323- meeting_session_id: int = Field(default=None, foreign_key="meeting_session.id")
2424- meeting_session: MeetingSession = Relationship(
2525- back_populates="attendances",
2626- sa_relationship_kwargs=dict(foreign_keys="[Attendance.meeting_session_id]"),
2727- )
2828- # User who is going to attend to the meeting session
2929- user_id: int = Field(foreign_key="user.id")
3030- user: User = Relationship(
3131- back_populates="attendances",
3232- sa_relationship_kwargs=dict(foreign_keys="[Attendance.user_id]"),
3333- )
+48
kefi/models/plazas/helpers.py
···11+import datetime
22+33+import pytz
44+from sqlmodel import Session, select
55+66+from kefi.config import settings
77+from kefi.models.core.helpers import available_balance
88+from kefi.models.core.models import Transaction, User
99+from kefi.models.plazas.models import Attendance, Plaza
1010+1111+1212+def next_plaza_appointment() -> datetime.datetime:
1313+ """Gets the next plaza date and time appointment."""
1414+ today = datetime.datetime.today()
1515+ next_date = (today + datetime.timedelta((4 - today.weekday()) % 7)).date()
1616+ default_time = datetime.time(hour=10, minute=0)
1717+ return datetime.datetime.combine(date=next_date, time=default_time).astimezone(
1818+ pytz.timezone("Europe/Madrid")
1919+ )
2020+2121+2222+def get_or_create_current_plaza(session: Session) -> Plaza:
2323+ """Gets the current available plaza."""
2424+ now = datetime.datetime.now()
2525+ query = select(Plaza).filter(Plaza.date >= now).order_by("date")
2626+ results = session.exec(query)
2727+ first = results.first()
2828+ if first:
2929+ return first
3030+ plaza = Plaza(date=next_plaza_appointment())
3131+ session.add(plaza)
3232+ return plaza
3333+3434+3535+def create_attendance(user: User, session: Session) -> Attendance:
3636+ """Creates the transaction that spends the kefis and also creates the attendance
3737+ for the next plaza.
3838+ """
3939+ plaza = get_or_create_current_plaza(session=session)
4040+ balance = available_balance(user=user, session=session)
4141+ price = settings.PLAZA_PRICE
4242+ if balance < price:
4343+ raise ValueError("The user doesn't have enough balance")
4444+ attendance = Attendance(plaza=plaza, user=user)
4545+ session.add(attendance)
4646+ transaction = Transaction(amount=-price, user=user, attendance=attendance)
4747+ session.add(transaction)
4848+ return attendance
+43
kefi/models/plazas/models.py
···11+import datetime
22+from typing import TYPE_CHECKING
33+44+from sqlmodel import Field, Relationship, SQLModel
55+66+from kefi.models.core.models import User
77+88+if TYPE_CHECKING:
99+1010+ from kefi.models.core.models import Transaction
1111+1212+1313+class Plaza(SQLModel, table=True):
1414+ """A plaza is a meeting session that represents a moment scheduled to create a
1515+ group call with the different groups of attendees.
1616+ """
1717+1818+ id: int | None = Field(default=None, primary_key=True)
1919+ date: datetime.datetime = Field(
2020+ unique=True, index=True
2121+ ) # When the meetings are going to be created
2222+ attendances: list["Attendance"] = Relationship(back_populates="plaza")
2323+2424+2525+class Attendance(SQLModel, table=True):
2626+ """An attendance is a user who has spent kefis to be part of a meetings session in
2727+ the plaza.
2828+ """
2929+3030+ id: int | None = Field(default=None, primary_key=True)
3131+ # Meeting session that the attendance makes reference
3232+ plaza_id: int = Field(foreign_key="plaza.id")
3333+ plaza: Plaza = Relationship(
3434+ back_populates="attendances",
3535+ sa_relationship_kwargs=dict(foreign_keys="[Attendance.plaza_id]"),
3636+ )
3737+ # User who is going to attend to the meeting session
3838+ user_id: int = Field(foreign_key="user.id")
3939+ user: User = Relationship(
4040+ back_populates="attendances",
4141+ sa_relationship_kwargs=dict(foreign_keys="[Attendance.user_id]"),
4242+ )
4343+ transactions: list["Transaction"] = Relationship(back_populates="attendance")