This commit is contained in:
Iliyan Angelov
2025-12-02 10:42:35 +02:00
parent 4b053ce703
commit 2d770dd27b
24 changed files with 1766 additions and 1402 deletions

View File

@@ -10,7 +10,7 @@ from ...security.middleware.auth import get_current_user, authorize_roles
from ...auth.models.user import User
from ..models.room import Room, RoomStatus
from ..models.room_type import RoomType
from ..schemas.room import CreateRoomRequest, UpdateRoomRequest, BulkDeleteRoomsRequest
from ..schemas.room import CreateRoomRequest, UpdateRoomRequest, BulkDeleteRoomsRequest, UpdateAmenityRequest
from ...shared.utils.response_helpers import success_response
from ...reviews.models.review import Review, ReviewStatus
from ...bookings.models.booking import Booking, BookingStatus
@@ -72,6 +72,112 @@ async def get_amenities(db: Session=Depends(get_db)):
logger.error(f'Error fetching amenities: {str(e)}', exc_info=True)
raise HTTPException(status_code=500, detail=str(e))
@router.put('/amenities/{old_name}', dependencies=[Depends(authorize_roles('admin'))])
async def update_amenity(old_name: str, request: UpdateAmenityRequest, current_user: User=Depends(authorize_roles('admin')), db: Session=Depends(get_db)):
"""Update/rename an amenity across all rooms and room types."""
try:
import json
updated_count = 0
# Update in room types
room_types = db.query(RoomType).all()
for rt in room_types:
if rt.amenities:
amenities_list = []
if isinstance(rt.amenities, list):
amenities_list = rt.amenities
elif isinstance(rt.amenities, str):
try:
amenities_list = json.loads(rt.amenities)
except:
amenities_list = [s.strip() for s in rt.amenities.split(',') if s.strip()]
if old_name in amenities_list:
amenities_list = [request.new_name if a == old_name else a for a in amenities_list]
rt.amenities = amenities_list
updated_count += 1
# Update in rooms
rooms = db.query(Room).all()
for room in rooms:
if room.amenities:
amenities_list = []
if isinstance(room.amenities, list):
amenities_list = room.amenities
elif isinstance(room.amenities, str):
try:
amenities_list = json.loads(room.amenities)
except:
amenities_list = [s.strip() for s in room.amenities.split(',') if s.strip()]
if old_name in amenities_list:
amenities_list = [request.new_name if a == old_name else a for a in amenities_list]
room.amenities = amenities_list
updated_count += 1
db.commit()
return success_response(
data={'updated_count': updated_count, 'old_name': old_name, 'new_name': request.new_name},
message=f'Amenity "{old_name}" updated to "{request.new_name}" in {updated_count} location(s)'
)
except Exception as e:
db.rollback()
logger.error(f'Error updating amenity: {str(e)}', exc_info=True)
raise HTTPException(status_code=500, detail=str(e))
@router.delete('/amenities/{amenity_name}', dependencies=[Depends(authorize_roles('admin'))])
async def delete_amenity(amenity_name: str, current_user: User=Depends(authorize_roles('admin')), db: Session=Depends(get_db)):
"""Remove an amenity from all rooms and room types."""
try:
import json
updated_count = 0
# Remove from room types
room_types = db.query(RoomType).all()
for rt in room_types:
if rt.amenities:
amenities_list = []
if isinstance(rt.amenities, list):
amenities_list = rt.amenities
elif isinstance(rt.amenities, str):
try:
amenities_list = json.loads(rt.amenities)
except:
amenities_list = [s.strip() for s in rt.amenities.split(',') if s.strip()]
if amenity_name in amenities_list:
amenities_list = [a for a in amenities_list if a != amenity_name]
rt.amenities = amenities_list if amenities_list else []
updated_count += 1
# Remove from rooms
rooms = db.query(Room).all()
for room in rooms:
if room.amenities:
amenities_list = []
if isinstance(room.amenities, list):
amenities_list = room.amenities
elif isinstance(room.amenities, str):
try:
amenities_list = json.loads(room.amenities)
except:
amenities_list = [s.strip() for s in room.amenities.split(',') if s.strip()]
if amenity_name in amenities_list:
amenities_list = [a for a in amenities_list if a != amenity_name]
room.amenities = amenities_list if amenities_list else []
updated_count += 1
db.commit()
return success_response(
data={'updated_count': updated_count, 'amenity_name': amenity_name},
message=f'Amenity "{amenity_name}" removed from {updated_count} location(s)'
)
except Exception as e:
db.rollback()
logger.error(f'Error deleting amenity: {str(e)}', exc_info=True)
raise HTTPException(status_code=500, detail=str(e))
@router.get('/room-types')
async def get_room_types(db: Session=Depends(get_db)):
"""Get all room types for dropdowns and forms."""
@@ -457,7 +563,21 @@ async def upload_room_images(id: int, images: List[UploadFile]=File(...), curren
continue
await f.write(content)
image_urls.append(f'/uploads/rooms/{filename}')
# Handle existing_images - it might be a list, a JSON string, or None
existing_images = room.images or []
if isinstance(existing_images, str):
# If it's a string, try to parse it as JSON
import json
try:
existing_images = json.loads(existing_images)
except (json.JSONDecodeError, TypeError):
# If parsing fails, treat as empty list
existing_images = []
# Ensure it's a list
if not isinstance(existing_images, list):
existing_images = []
updated_images = existing_images + image_urls
room.images = updated_images
db.commit()
@@ -483,7 +603,21 @@ async def delete_room_images(id: int, image_url: str=Query(..., description='Ima
if not normalized_url.startswith('/'):
normalized_url = f'/{normalized_url}'
filename = Path(normalized_url).name
# Handle existing_images - it might be a list, a JSON string, or None
existing_images = room.images or []
if isinstance(existing_images, str):
# If it's a string, try to parse it as JSON
import json
try:
existing_images = json.loads(existing_images)
except (json.JSONDecodeError, TypeError):
# If parsing fails, treat as empty list
existing_images = []
# Ensure it's a list
if not isinstance(existing_images, list):
existing_images = []
updated_images = []
for img in existing_images:
stored_path = img if img.startswith('/') else f'/{img}'