Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Booking enhancements #280

Merged
merged 12 commits into from
Dec 18, 2023
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,5 @@ firebase.json
# Logs
logs/

# Migrations scripts
migrations/versions/*.py

# Pytest-cov
.coverage
42 changes: 29 additions & 13 deletions app/endpoints/booking.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,14 +183,36 @@ async def get_bookings_for_manager(


@router.get(
"/booking/bookings/confirmed",
response_model=list[schemas_booking.BookingReturn],
"/booking/bookings/confirmed/users/me/manage",
response_model=list[schemas_booking.BookingReturnApplicant],
Petitoto marked this conversation as resolved.
Show resolved Hide resolved
status_code=200,
tags=[Tags.booking],
)
async def get_confirmed_bookings_for_manager(
db: AsyncSession = Depends(get_db),
user: models_core.CoreUser = Depends(is_user_a_member),
):
"""
Return all confirmed bookings a user can manage.
**The user must be authenticated to use this endpoint**
"""

user_managers = await cruds_booking.get_user_managers(user=user, db=db)

bookings = await cruds_booking.get_confirmed_bookings(db=db)

return [booking for booking in bookings if booking.room.manager in user_managers]


@router.get(
"/booking/bookings/confirmed",
response_model=list[schemas_booking.BookingReturnSimpleApplicant],
status_code=200,
tags=[Tags.booking],
)
async def get_confirmed_bookings(
db: AsyncSession = Depends(get_db),
user: models_core.CoreUser = Depends(is_user_a_member),
):
"""
Return all confirmed bookings.
Expand All @@ -204,28 +226,22 @@ async def get_confirmed_bookings_for_manager(


@router.get(
"/booking/bookings/users/{applicant_id}",
"/booking/bookings/users/me",
response_model=list[schemas_booking.BookingReturn],
status_code=200,
tags=[Tags.booking],
)
async def get_applicant_bookings(
applicant_id: str,
db: AsyncSession = Depends(get_db),
user: models_core.CoreUser = Depends(is_user_a_member),
):
"""
Get one user bookings.
Get the user bookings.

**Only usable by the user**
"""
if user.id == applicant_id:
bookings = await cruds_booking.get_applicant_bookings(
db=db, applicant_id=applicant_id
)
return bookings
else:
raise HTTPException(status_code=403)
bookings = await cruds_booking.get_applicant_bookings(db=db, applicant_id=user.id)
return bookings


@router.post(
Expand Down Expand Up @@ -344,7 +360,7 @@ async def confirm_booking(
else:
raise HTTPException(
status_code=403,
detail="You are not allowed to delete this booking",
detail="You are not allowed to give a decision to this booking",
)


Expand Down
1 change: 1 addition & 0 deletions app/models/models_booking.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class Booking(Base):
reason: Mapped[str] = mapped_column(String, nullable=False)
start: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False)
end: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False)
creation: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False)
note: Mapped[str] = mapped_column(String, nullable=True)
room_id: Mapped[str] = mapped_column(
ForeignKey("booking_room.id"), nullable=False, index=True
Expand Down
9 changes: 7 additions & 2 deletions app/schemas/schemas_booking.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""Schemas file for endpoint /bdebooking"""
"""Schemas file for endpoint /booking"""

from datetime import datetime

Expand Down Expand Up @@ -46,6 +46,7 @@ class BookingBase(BaseModel):
reason: str
start: datetime
end: datetime
creation: datetime
note: str | None
room_id: str
key: bool
Expand All @@ -72,6 +73,10 @@ class Config:
orm_mode = True


class BookingReturnSimpleApplicant(BookingReturn):
applicant: CoreUserSimple


class BookingReturnApplicant(BookingReturn):
applicant: Applicant

Expand All @@ -81,7 +86,7 @@ class BookingEdit(BaseModel):
start: datetime | None = None
end: datetime | None = None
note: str | None = None
room: str | None = None
room_id: str | None = None
key: bool | None = None
recurrence_rule: str | None = None
entity: str | None = None
2 changes: 1 addition & 1 deletion app/utils/types/module_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class ModuleList(Module, Enum):
root="amap",
default_allowed_groups_ids=[GroupType.student, GroupType.staff],
)
bdebooking = Module(
booking = Module(
root="booking",
default_allowed_groups_ids=[GroupType.student, GroupType.staff],
)
Expand Down
Empty file removed migrations/versions/.gitkeep
Empty file.
60 changes: 60 additions & 0 deletions migrations/versions/28aa5ef44bf3_booking_enhancements.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
"""booking enhancements

Revision ID: 28aa5ef44bf3
Revises:
Create Date: 2023-12-18 00:35:59.678336

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = "28aa5ef44bf3"
down_revision = None
branch_labels = None
depends_on = None


def upgrade() -> None:
# Schema migration
op.add_column(
"booking",
sa.Column(
"creation",
sa.DateTime(timezone=True),
nullable=False,
server_default=sa.func.now(),
),
)

# Data migration
t_booking = sa.Table(
"booking",
sa.MetaData(),
sa.Column("id", sa.String()),
sa.Column("start", sa.DateTime()),
sa.Column("end", sa.DateTime()),
sa.Column("recurrence_rule", sa.String()),
)

conn = op.get_bind()
res = conn.execute(
sa.select(t_booking.c.id, t_booking.c.start, t_booking.c.end).where(
t_booking.c.recurrence_rule != ""
)
).fetchall()
for id_, booking_start, booking_end in res:
endBooking = booking_end.replace(
year=booking_start.year,
month=booking_start.month,
day=booking_start.day,
)
endBooking = endBooking.astimezone().replace(tzinfo=None)
conn.execute(
t_booking.update().where(t_booking.c.id == id_).values(end=endBooking)
)


def downgrade() -> None:
# Schema migration
op.drop_column("booking", "creation")
19 changes: 17 additions & 2 deletions tests/test_booking.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,16 @@ async def init_objects():
)
await add_object_to_db(room_to_delete)

global booking_id
booking_id = str(uuid.uuid4())

global booking
booking = models_booking.Booking(
id=str(uuid.uuid4()),
id=booking_id,
reason="HH",
start=datetime.datetime.fromisoformat("2023-09-22T20:00:00"),
end=datetime.datetime.fromisoformat("2023-09-22T23:00:00"),
creation=datetime.datetime.fromisoformat("2023-09-10T10:00:00"),
room_id=room.id,
key=True,
decision="approved",
Expand All @@ -101,6 +105,7 @@ async def init_objects():
reason="Test",
start=datetime.datetime.fromisoformat("2023-09-22T20:00:00"),
end=datetime.datetime.fromisoformat("2023-09-22T23:00:00"),
creation=datetime.datetime.fromisoformat("2023-09-10T10:00:00"),
room_id=room.id,
key=True,
decision="pending",
Expand Down Expand Up @@ -171,6 +176,15 @@ def test_get_user_bookings_manage():


def test_get_user_bookings_manage_confirmed():
response = client.get(
"/booking/bookings/confirmed/users/me/manage",
headers={"Authorization": f"Bearer {token_manager}"},
)
assert response.status_code == 200
assert booking_id in map(lambda booking: booking["id"], response.json())


def test_get_bookings_confirmed():
response = client.get(
"/booking/bookings/confirmed",
headers={"Authorization": f"Bearer {token_manager}"},
Expand All @@ -180,7 +194,7 @@ def test_get_user_bookings_manage_confirmed():

def test_get_user_bookings():
response = client.get(
f"/booking/bookings/users/{simple_user.id}",
"/booking/bookings/users/me",
headers={"Authorization": f"Bearer {token_simple}"},
)
assert response.status_code == 200
Expand All @@ -193,6 +207,7 @@ def test_post_bookings():
"reason": "Test",
"start": "2022-09-15T08:00:00Z",
"end": "2022-09-15T09:00:00Z",
"creation": "2022-09-15T07:00:00Z",
"note": "do",
"room_id": room.id,
"key": True,
Expand Down