From 1a18347e93742e2ad2abc25499f360c73c704b37 Mon Sep 17 00:00:00 2001 From: Felipe Cardoso Date: Sun, 16 Mar 2025 20:23:52 +0100 Subject: [PATCH] Fix several problems with gift registry api --- backend/app/api/routes/events/gifts.py | 11 ++++++--- backend/app/api/routes/events/router.py | 3 ++- backend/app/crud/base.py | 4 ++- backend/app/crud/gift.py | 33 ++++++++++++++++--------- 4 files changed, 33 insertions(+), 18 deletions(-) diff --git a/backend/app/api/routes/events/gifts.py b/backend/app/api/routes/events/gifts.py index 769b960..b3f1d1a 100644 --- a/backend/app/api/routes/events/gifts.py +++ b/backend/app/api/routes/events/gifts.py @@ -926,8 +926,13 @@ def cancel_gift_reservation( # For admin users, allow direct cancellation if current_user: - return gift_item_crud.cancel_reservation(db, gift_id=item_id, guest_id=guest_id) + try: + return gift_item_crud.cancel_reservation(db, gift_id=item_id, guest_id=guest_id) + except ValueError as e: + raise HTTPException(status_code=400, detail=str(e)) + # Missing the return statement here, which is also a problem + return gift_item_crud.cancel_reservation(db, gift_id=item_id, guest_id=guest_id) # ===== GIFT PURCHASES ===== # @@ -1042,6 +1047,4 @@ def read_gift_purchases_by_guest( if not event or not event.is_public: raise HTTPException(status_code=403, detail="Not enough permissions") - gifts = gift_purchase_crud.get_gift_reservations_by_guest(db, guest_id=guest_id) - print(gifts) - return gifts + return gift_purchase_crud.get_gift_reservations_by_guest(db, guest_id=guest_id) diff --git a/backend/app/api/routes/events/router.py b/backend/app/api/routes/events/router.py index 2009a5e..0ef3687 100644 --- a/backend/app/api/routes/events/router.py +++ b/backend/app/api/routes/events/router.py @@ -271,11 +271,12 @@ def get_event_by_slug( db: Session = Depends(get_db), slug: str, access_code: Optional[str] = Query(None), - current_user: Optional[User] = Depends(get_current_user) + current_user: Optional[User] = Depends(get_optional_current_user) ) -> EventResponse: """Get event by slug.""" try: event_obj = event_crud.get_by_slug(db=db, slug=slug) + print(f"Event {event_obj}") return validate_event_access( db=db, event_obj=event_obj, diff --git a/backend/app/crud/base.py b/backend/app/crud/base.py index 18c27c2..ffdd842 100644 --- a/backend/app/crud/base.py +++ b/backend/app/crud/base.py @@ -1,4 +1,6 @@ from typing import Any, Dict, Generic, List, Optional, Type, TypeVar, Union +from uuid import UUID + from fastapi.encoders import jsonable_encoder from pydantic import BaseModel from sqlalchemy.orm import Session @@ -19,7 +21,7 @@ class CRUDBase(Generic[ModelType, CreateSchemaType, UpdateSchemaType]): """ self.model = model - def get(self, db: Session, id: str) -> Optional[ModelType]: + def get(self, db: Session, id: UUID | str) -> Optional[ModelType]: return db.query(self.model).filter(self.model.id == id).first() def get_multi( diff --git a/backend/app/crud/gift.py b/backend/app/crud/gift.py index efbaa88..d77b64b 100644 --- a/backend/app/crud/gift.py +++ b/backend/app/crud/gift.py @@ -121,26 +121,35 @@ class CRUDGiftItem(CRUDBase[GiftItem, GiftItemCreate, GiftItemUpdate]): return gift def cancel_reservation( - self, db: Session, *, gift_id: UUID, guest_id: UUID + self, db: Session, *, gift_id: UUID | str, guest_id: UUID | str ) -> GiftItem: """Cancel a gift reservation""" + gift_id = UUID(gift_id) if isinstance(gift_id, str) else gift_id gift = self.get(db, gift_id) - guest = db.query(Guest).get(guest_id) - if gift and gift.status == GiftStatus.RESERVED: - # Using the ORM relationship approach + if not gift: + raise ValueError(f"Gift with ID {gift_id} not found") + + guest_id = UUID(guest_id) if isinstance(guest_id, str) else guest_id + guest = db.query(Guest).get(guest_id) + if not guest: + raise ValueError(f"Guest with ID {guest_id} not found") + + # Only perform the operation if the gift is reserved + if gift.status == GiftStatus.RESERVED: + # Check if this guest has actually reserved this gift if guest in gift.reserved_by: gift.reserved_by.remove(guest) - # Update gift status - gift.status = GiftStatus.AVAILABLE - gift.last_status_change = datetime.now(timezone.utc) + # Only change status if no other guests have reserved this gift + if not gift.reserved_by: + gift.status = GiftStatus.AVAILABLE + gift.last_status_change = datetime.now(timezone.utc) - db.commit() - db.refresh(gift) - - return gift + db.commit() + db.refresh(gift) + return gift # Always return the gift object, even if no changes were made class CRUDEventGiftCategory: def create(self, db: Session, *, obj_in: EventGiftCategoryCreate) -> EventGiftCategory: @@ -314,7 +323,6 @@ class CRUDGiftPurchase(CRUDBase[GiftPurchase, GiftPurchaseCreate, GiftPurchaseUp self, db: Session, *, guest_id: UUID | str ) -> List[GiftPurchase]: """Convert gift reservations to purchase-like objects for API compatibility""" - print(f"Getting all gift reservations of: {guest_id}") guest_id = guest_id if isinstance(guest_id, UUID) else UUID(guest_id) # Query the guest object first @@ -351,6 +359,7 @@ class CRUDGiftPurchase(CRUDBase[GiftPurchase, GiftPurchaseCreate, GiftPurchaseUp return result + # Create CRUD instances gift_item_crud = CRUDGiftItem(GiftItem) gift_category_crud = CRUDGiftCategory(GiftCategory)