diff --git a/backend/app/api/routes/events/gifts.py b/backend/app/api/routes/events/gifts.py index 86965eb..3083b5e 100644 --- a/backend/app/api/routes/events/gifts.py +++ b/backend/app/api/routes/events/gifts.py @@ -854,11 +854,13 @@ def reserve_gift_item( db: Session = Depends(get_db), item_id: UUID = Path(...), guest_id: UUID, + quantity: Optional[int] = 1, notes: Optional[str] = None, current_user: Optional[User] = Depends(get_current_user) ) -> Any: """ - Reserve a gift item for a guest. + Reserve a gift item for a guest with specified quantity. + Default quantity is 1 if not provided. """ gift = gift_item_crud.get(db, id=item_id) if not gift: @@ -868,6 +870,15 @@ def reserve_gift_item( if gift.status != GiftStatus.AVAILABLE: raise HTTPException(status_code=400, detail="Gift is not available for reservation") + # Validate quantity + if quantity <= 0: + raise HTTPException(status_code=400, detail="Quantity must be a positive number") + + # Check if requested quantity is valid + if quantity > gift.remaining_quantity: + raise HTTPException(status_code=400, + detail=f"Requested quantity ({quantity}) exceeds available quantity ({gift.remaining_quantity})") + # Check if guest exists guest = guest_crud.get(db, id=guest_id) if not guest: @@ -879,7 +890,7 @@ def reserve_gift_item( # For admin users, allow direct reservation if current_user: - return gift_item_crud.reserve_gift(db, gift_id=item_id, guest_id=guest_id, notes=notes) + return gift_item_crud.reserve_gift(db, gift_id=item_id, guest_id=guest_id, quantity=quantity, notes=notes) # For public users, additional validation # Check if event is public @@ -887,8 +898,7 @@ def reserve_gift_item( if not event or not event.is_public: raise HTTPException(status_code=403, detail="Not enough permissions") - return gift_item_crud.reserve_gift(db, gift_id=item_id, guest_id=guest_id, notes=notes) - + return gift_item_crud.reserve_gift(db, gift_id=item_id, guest_id=guest_id, quantity=quantity, notes=notes) @router.post("/items/{item_id}/cancel-reservation", response_model=GiftItem, operation_id="cancel_gift_reservation") def cancel_gift_reservation( diff --git a/backend/app/crud/gift.py b/backend/app/crud/gift.py index b03945e..9a5604c 100644 --- a/backend/app/crud/gift.py +++ b/backend/app/crud/gift.py @@ -87,9 +87,9 @@ class CRUDGiftItem(CRUDBase[GiftItem, GiftItemCreate, GiftItemUpdate]): return gift def reserve_gift( - self, db: Session, *, gift_id: UUID, guest_id: UUID, notes: Optional[str] = None + self, db: Session, *, gift_id: UUID, guest_id: UUID, quantity: int = 1, notes: Optional[str] = None ) -> GiftItem: - """Reserve a gift for a guest""" + """Reserve a gift for a guest with specified quantity""" gift = self.get(db, gift_id) if gift and gift.status == GiftStatus.AVAILABLE: @@ -104,10 +104,18 @@ class CRUDGiftItem(CRUDBase[GiftItem, GiftItemCreate, GiftItemUpdate]): ) db.execute(stmt) - # Update gift status + # Update gift status and quantity gift.status = GiftStatus.RESERVED gift.last_status_change = datetime.now(timezone.utc) + # Record the reservation quantity by updating quantity_received + # This effectively reduces the remaining_quantity + gift.quantity_received += quantity + + # If fully received, ensure status reflects that + if gift.quantity_received >= gift.quantity_requested: + gift.status = GiftStatus.RECEIVED + db.commit() db.refresh(gift) return gift @@ -159,7 +167,7 @@ class CRUDEventGiftCategory: ).first() def update( - self, db: Session, *, db_obj: EventGiftCategory, obj_in: Union[EventGiftCategoryUpdate, Dict[str, Any]] + self, db: Session, *, db_obj: EventGiftCategory, obj_in: Union[EventGiftCategoryUpdate, Dict[str, Any]] ) -> EventGiftCategory: """Update an event-category association""" if isinstance(obj_in, dict):