update
This commit is contained in:
@@ -12,6 +12,7 @@ from ..models.guest_request import GuestRequest, RequestType, RequestStatus, Req
|
||||
from ...bookings.models.booking import Booking, BookingStatus
|
||||
from ...rooms.models.room import Room
|
||||
from pydantic import BaseModel
|
||||
from ...shared.utils.sanitization import sanitize_text
|
||||
|
||||
logger = get_logger(__name__)
|
||||
router = APIRouter(prefix='/guest-requests', tags=['guest-requests'])
|
||||
@@ -163,18 +164,135 @@ async def create_guest_request(
|
||||
if booking.room_id != request_data.room_id:
|
||||
raise HTTPException(status_code=400, detail='Room ID does not match booking')
|
||||
|
||||
# Sanitize user input to prevent XSS
|
||||
sanitized_title = sanitize_text(request_data.title)
|
||||
sanitized_description = sanitize_text(request_data.description) if request_data.description else None
|
||||
sanitized_guest_notes = sanitize_text(request_data.guest_notes) if request_data.guest_notes else None
|
||||
|
||||
guest_request = GuestRequest(
|
||||
booking_id=request_data.booking_id,
|
||||
room_id=request_data.room_id,
|
||||
user_id=current_user.id,
|
||||
request_type=RequestType(request_data.request_type),
|
||||
priority=RequestPriority(request_data.priority),
|
||||
title=request_data.title,
|
||||
description=request_data.description,
|
||||
guest_notes=request_data.guest_notes,
|
||||
title=sanitized_title,
|
||||
description=sanitized_description,
|
||||
guest_notes=sanitized_guest_notes,
|
||||
)
|
||||
|
||||
db.add(guest_request)
|
||||
db.flush() # Flush to get the ID for task creation
|
||||
|
||||
# Auto-create housekeeping task for request types that require housekeeping
|
||||
request_type = RequestType(request_data.request_type)
|
||||
task_types_requiring_housekeeping = {
|
||||
RequestType.extra_towels,
|
||||
RequestType.extra_pillows,
|
||||
RequestType.room_cleaning,
|
||||
RequestType.turndown_service,
|
||||
RequestType.amenities,
|
||||
}
|
||||
|
||||
if request_type in task_types_requiring_housekeeping:
|
||||
try:
|
||||
from ...hotel_services.models.housekeeping_task import HousekeepingTask, HousekeepingStatus, HousekeepingType
|
||||
from ...rooms.models.room import Room
|
||||
|
||||
# Determine housekeeping task type based on request type
|
||||
task_type_map = {
|
||||
RequestType.room_cleaning: HousekeepingType.stayover,
|
||||
RequestType.turndown_service: HousekeepingType.turndown,
|
||||
RequestType.extra_towels: HousekeepingType.stayover,
|
||||
RequestType.extra_pillows: HousekeepingType.stayover,
|
||||
RequestType.amenities: HousekeepingType.stayover,
|
||||
}
|
||||
|
||||
housekeeping_task_type = task_type_map.get(request_type, HousekeepingType.stayover)
|
||||
|
||||
# Create default checklist based on request type
|
||||
checklist_items = []
|
||||
if request_type == RequestType.room_cleaning:
|
||||
checklist_items = [
|
||||
{'item': 'Room cleaned', 'completed': False, 'notes': ''},
|
||||
{'item': 'Bathroom cleaned', 'completed': False, 'notes': ''},
|
||||
{'item': 'Trash emptied', 'completed': False, 'notes': ''},
|
||||
{'item': 'Beds made', 'completed': False, 'notes': ''},
|
||||
]
|
||||
elif request_type == RequestType.turndown_service:
|
||||
checklist_items = [
|
||||
{'item': 'Beds turned down', 'completed': False, 'notes': ''},
|
||||
{'item': 'Curtains closed', 'completed': False, 'notes': ''},
|
||||
{'item': 'Lights dimmed', 'completed': False, 'notes': ''},
|
||||
{'item': 'Amenities refreshed', 'completed': False, 'notes': ''},
|
||||
]
|
||||
elif request_type in [RequestType.extra_towels, RequestType.extra_pillows, RequestType.amenities]:
|
||||
item_name = 'Extra towels' if request_type == RequestType.extra_towels else \
|
||||
'Extra pillows' if request_type == RequestType.extra_pillows else 'Amenities'
|
||||
checklist_items = [
|
||||
{'item': f'{item_name} delivered', 'completed': False, 'notes': request_data.description or ''},
|
||||
]
|
||||
|
||||
# Check if a similar task already exists for this room
|
||||
existing_task = db.query(HousekeepingTask).filter(
|
||||
and_(
|
||||
HousekeepingTask.room_id == request_data.room_id,
|
||||
HousekeepingTask.task_type == housekeeping_task_type,
|
||||
HousekeepingTask.status.in_([HousekeepingStatus.pending, HousekeepingStatus.in_progress]),
|
||||
HousekeepingTask.booking_id == request_data.booking_id
|
||||
)
|
||||
).first()
|
||||
|
||||
if not existing_task:
|
||||
# Create housekeeping task
|
||||
housekeeping_task = HousekeepingTask(
|
||||
room_id=request_data.room_id,
|
||||
booking_id=request_data.booking_id,
|
||||
task_type=housekeeping_task_type,
|
||||
status=HousekeepingStatus.pending,
|
||||
scheduled_time=datetime.utcnow(), # Schedule immediately for guest requests
|
||||
created_by=None, # Created by system/guest request
|
||||
checklist_items=checklist_items,
|
||||
notes=f'Auto-created from guest request: {request_data.title}. Guest notes: {request_data.guest_notes or "None"}',
|
||||
estimated_duration_minutes=15 if request_type in [RequestType.extra_towels, RequestType.extra_pillows, RequestType.amenities] else 30
|
||||
)
|
||||
|
||||
db.add(housekeeping_task)
|
||||
db.flush()
|
||||
|
||||
# Link guest request to housekeeping task via notes
|
||||
guest_request.staff_notes = f'Auto-created housekeeping task #{housekeeping_task.id}'
|
||||
|
||||
# Send notification to housekeeping users
|
||||
try:
|
||||
from ...notifications.routes.notification_routes import notification_manager
|
||||
room = db.query(Room).filter(Room.id == request_data.room_id).first()
|
||||
|
||||
task_data_notification = {
|
||||
'id': housekeeping_task.id,
|
||||
'room_id': housekeeping_task.room_id,
|
||||
'room_number': room.room_number if room else None,
|
||||
'task_type': housekeeping_task.task_type.value,
|
||||
'status': housekeeping_task.status.value,
|
||||
'scheduled_time': housekeeping_task.scheduled_time.isoformat() if housekeeping_task.scheduled_time else None,
|
||||
'guest_request_id': guest_request.id,
|
||||
'guest_request_title': request_data.title,
|
||||
'created_at': housekeeping_task.created_at.isoformat() if housekeeping_task.created_at else None
|
||||
}
|
||||
notification_data = {
|
||||
'type': 'housekeeping_task_available',
|
||||
'data': task_data_notification
|
||||
}
|
||||
|
||||
# Send notification to all housekeeping users
|
||||
await notification_manager.send_to_role('housekeeping', notification_data)
|
||||
except Exception as e:
|
||||
logger.error(f'Error sending housekeeping notification for guest request: {str(e)}', exc_info=True)
|
||||
|
||||
logger.info(f'Auto-created housekeeping task {housekeeping_task.id} for guest request {guest_request.id} (type: {request_type.value})')
|
||||
except Exception as e:
|
||||
# Don't fail guest request creation if task creation fails
|
||||
logger.error(f'Error auto-creating housekeeping task for guest request: {str(e)}', exc_info=True)
|
||||
|
||||
db.commit()
|
||||
db.refresh(guest_request)
|
||||
|
||||
@@ -378,7 +496,8 @@ async def fulfill_request(
|
||||
request.fulfilled_at = datetime.utcnow()
|
||||
|
||||
if staff_notes:
|
||||
request.staff_notes = (request.staff_notes or '') + f'\n{staff_notes}' if request.staff_notes else staff_notes
|
||||
sanitized_notes = sanitize_text(staff_notes)
|
||||
request.staff_notes = (request.staff_notes or '') + f'\n{sanitized_notes}' if request.staff_notes else sanitized_notes
|
||||
|
||||
if request.started_at:
|
||||
delta = datetime.utcnow() - request.started_at
|
||||
|
||||
Reference in New Issue
Block a user