hospitality-expert by personamanagmentlayer/pcl
npx skills add https://github.com/personamanagmentlayer/pcl --skill hospitality-expert为酒店管理、预订系统、物业管理系统(PMS)、宾客服务、收益管理和酒店技术解决方案提供专业指导。
from dataclasses import dataclass
from datetime import datetime, timedelta, date
from typing import List, Optional, Dict
from decimal import Decimal
from enum import Enum
class RoomType(Enum):
STANDARD = "standard"
DELUXE = "deluxe"
SUITE = "suite"
EXECUTIVE = "executive"
class RoomStatus(Enum):
VACANT_CLEAN = "vacant_clean"
VACANT_DIRTY = "vacant_dirty"
OCCUPIED_CLEAN = "occupied_clean"
OCCUPIED_DIRTY = "occupied_dirty"
OUT_OF_ORDER = "out_of_order"
OUT_OF_SERVICE = "out_of_service"
class ReservationStatus(Enum):
CONFIRMED = "confirmed"
CHECKED_IN = "checked_in"
CHECKED_OUT = "checked_out"
CANCELLED = "cancelled"
NO_SHOW = "no_show"
@dataclass
class Room:
"""酒店客房信息"""
room_number: str
room_type: RoomType
floor: int
status: RoomStatus
base_rate: Decimal
features: List[str]
bed_type: str
max_occupancy: int
square_feet: int
is_smoking: bool
@dataclass
class Reservation:
"""宾客预订"""
reservation_id: str
guest_name: str
guest_email: str
guest_phone: str
room_type: RoomType
check_in_date: date
check_out_date: date
num_adults: int
num_children: int
status: ReservationStatus
rate_per_night: Decimal
total_amount: Decimal
special_requests: str
created_at: datetime
booking_source: str # 'direct', 'ota', 'phone', etc.
assigned_room: Optional[str]
@dataclass
class Folio:
"""宾客账单"""
folio_id: str
reservation_id: str
room_number: str
guest_name: str
charges: List[Dict]
total_charges: Decimal
payments: List[Dict]
balance: Decimal
class PropertyManagementSystem:
"""酒店物业管理系统"""
def __init__(self):
self.rooms = {}
self.reservations = {}
self.folios = {}
self.guests = {}
def create_reservation(self, reservation_data: dict) -> Reservation:
"""创建新预订"""
reservation_id = self._generate_reservation_id()
# 计算总金额
check_in = reservation_data['check_in_date']
check_out = reservation_data['check_out_date']
num_nights = (check_out - check_in).days
rate_per_night = Decimal(str(reservation_data['rate_per_night']))
total_amount = rate_per_night * num_nights
reservation = Reservation(
reservation_id=reservation_id,
guest_name=reservation_data['guest_name'],
guest_email=reservation_data['guest_email'],
guest_phone=reservation_data['guest_phone'],
room_type=RoomType(reservation_data['room_type']),
check_in_date=check_in,
check_out_date=check_out,
num_adults=reservation_data['num_adults'],
num_children=reservation_data.get('num_children', 0),
status=ReservationStatus.CONFIRMED,
rate_per_night=rate_per_night,
total_amount=total_amount,
special_requests=reservation_data.get('special_requests', ''),
created_at=datetime.now(),
booking_source=reservation_data.get('booking_source', 'direct'),
assigned_room=None
)
self.reservations[reservation_id] = reservation
return reservation
def check_in_guest(self, reservation_id: str) -> dict:
"""处理宾客入住"""
reservation = self.reservations.get(reservation_id)
if not reservation:
return {'error': '未找到预订'}
# 查找请求房型的可用房间
available_room = self._find_available_room(
reservation.room_type,
reservation.check_in_date,
reservation.check_out_date
)
if not available_room:
return {'error': '请求的房型无可用房间'}
# 分配房间
reservation.assigned_room = available_room.room_number
reservation.status = ReservationStatus.CHECKED_IN
# 更新房间状态
available_room.status = RoomStatus.OCCUPIED_CLEAN
# 创建账单
folio = self._create_folio(reservation, available_room)
return {
'reservation_id': reservation_id,
'room_number': available_room.room_number,
'guest_name': reservation.guest_name,
'check_in_time': datetime.now().isoformat(),
'check_out_date': reservation.check_out_date.isoformat(),
'folio_id': folio.folio_id
}
def check_out_guest(self, reservation_id: str) -> dict:
"""处理宾客退房"""
reservation = self.reservations.get(reservation_id)
if not reservation:
return {'error': '未找到预订'}
# 获取账单
folio = next(
(f for f in self.folios.values() if f.reservation_id == reservation_id),
None
)
if not folio:
return {'error': '未找到账单'}
# 检查未结余额
if folio.balance > 0:
return {
'error': '有待付余额',
'balance_due': float(folio.balance)
}
# 更新预订状态
reservation.status = ReservationStatus.CHECKED_OUT
# 更新房间状态
if reservation.assigned_room:
room = self.rooms.get(reservation.assigned_room)
if room:
room.status = RoomStatus.VACANT_DIRTY
return {
'reservation_id': reservation_id,
'guest_name': reservation.guest_name,
'check_out_time': datetime.now().isoformat(),
'total_charges': float(folio.total_charges),
'folio_summary': {
'room_charges': float(folio.total_charges),
'payments_received': float(folio.total_charges - folio.balance)
}
}
def _find_available_room(self,
room_type: RoomType,
check_in: date,
check_out: date) -> Optional[Room]:
"""查找指定房型的可用房间"""
for room in self.rooms.values():
if room.room_type != room_type:
continue
if room.status not in [RoomStatus.VACANT_CLEAN, RoomStatus.VACANT_DIRTY]:
continue
# 检查房间在日期范围内是否可用
if self._is_room_available(room.room_number, check_in, check_out):
return room
return None
def _is_room_available(self, room_number: str, check_in: date, check_out: date) -> bool:
"""检查房间在日期范围内是否可用"""
for reservation in self.reservations.values():
if reservation.assigned_room != room_number:
continue
if reservation.status in [ReservationStatus.CANCELLED, ReservationStatus.NO_SHOW]:
continue
# 检查日期重叠
if not (check_out <= reservation.check_in_date or check_in >= reservation.check_out_date):
return False
return True
def _create_folio(self, reservation: Reservation, room: Room) -> Folio:
"""创建宾客账单"""
folio_id = self._generate_folio_id()
# 计算房费
num_nights = (reservation.check_out_date - reservation.check_in_date).days
room_charge = reservation.rate_per_night * num_nights
charges = [{
'date': datetime.now(),
'description': f'房间 {room.room_number} - {num_nights} 晚',
'amount': float(room_charge)
}]
folio = Folio(
folio_id=folio_id,
reservation_id=reservation.reservation_id,
room_number=room.room_number,
guest_name=reservation.guest_name,
charges=charges,
total_charges=room_charge,
payments=[],
balance=room_charge
)
self.folios[folio_id] = folio
return folio
def post_charge(self, folio_id: str, charge_data: dict) -> dict:
"""向宾客账单添加费用"""
folio = self.folios.get(folio_id)
if not folio:
return {'error': '未找到账单'}
charge = {
'date': datetime.now(),
'description': charge_data['description'],
'amount': float(Decimal(str(charge_data['amount'])))
}
folio.charges.append(charge)
folio.total_charges += Decimal(str(charge_data['amount']))
folio.balance += Decimal(str(charge_data['amount']))
return {
'folio_id': folio_id,
'charge_posted': charge,
'new_balance': float(folio.balance)
}
def process_payment(self, folio_id: str, payment_data: dict) -> dict:
"""处理账单付款"""
folio = self.folios.get(folio_id)
if not folio:
return {'error': '未找到账单'}
payment_amount = Decimal(str(payment_data['amount']))
if payment_amount > folio.balance:
return {'error': '付款金额超过余额'}
payment = {
'date': datetime.now(),
'payment_method': payment_data['payment_method'],
'amount': float(payment_amount)
}
folio.payments.append(payment)
folio.balance -= payment_amount
return {
'folio_id': folio_id,
'payment_processed': payment,
'remaining_balance': float(folio.balance)
}
def get_room_availability(self, check_in: date, check_out: date) -> dict:
"""获取日期范围内的房间可用性"""
availability = {}
for room_type in RoomType:
available_count = 0
for room in self.rooms.values():
if room.room_type == room_type:
if self._is_room_available(room.room_number, check_in, check_out):
available_count += 1
availability[room_type.value] = available_count
return {
'check_in_date': check_in.isoformat(),
'check_out_date': check_out.isoformat(),
'availability': availability
}
def _generate_reservation_id(self) -> str:
import uuid
return f"RES-{uuid.uuid4().hex[:10].upper()}"
def _generate_folio_id(self) -> str:
import uuid
return f"FOL-{uuid.uuid4().hex[:8].upper()}"
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
import numpy as np
class RevenueManagementSystem:
"""酒店收益管理和动态定价"""
def __init__(self):
self.pricing_rules = []
self.demand_forecast = {}
def calculate_dynamic_rate(self,
room_type: RoomType,
check_in_date: date,
days_until_arrival: int,
current_occupancy: float,
historical_data: dict) -> Decimal:
"""计算动态房价"""
# 基础房价
base_rates = {
RoomType.STANDARD: Decimal('150'),
RoomType.DELUXE: Decimal('200'),
RoomType.SUITE: Decimal('350'),
RoomType.EXECUTIVE: Decimal('450')
}
base_rate = base_rates.get(room_type, Decimal('150'))
# 基于入住率的需求乘数
if current_occupancy > 0.85:
demand_multiplier = Decimal('1.30') # 高需求
elif current_occupancy > 0.70:
demand_multiplier = Decimal('1.15') # 中等需求
elif current_occupancy > 0.50:
demand_multiplier = Decimal('1.00') # 正常
else:
demand_multiplier = Decimal('0.85') # 低需求
# 预订窗口乘数
if days_until_arrival < 7:
window_multiplier = Decimal('1.20') # 最后一刻
elif days_until_arrival < 14:
window_multiplier = Decimal('1.10')
elif days_until_arrival > 60:
window_multiplier = Decimal('0.90') # 提前预订
else:
window_multiplier = Decimal('1.00')
# 星期几调整
if check_in_date.weekday() in [4, 5]: # 周五、周六
day_multiplier = Decimal('1.25')
elif check_in_date.weekday() == 6: # 周日
day_multiplier = Decimal('0.95')
else:
day_multiplier = Decimal('1.00')
# 计算最终房价
dynamic_rate = base_rate * demand_multiplier * window_multiplier * day_multiplier
# 四舍五入到最接近的美元
dynamic_rate = dynamic_rate.quantize(Decimal('1'))
return dynamic_rate
def forecast_demand(self, start_date: date, days: int) -> dict:
"""预测未来期间的需求"""
forecast = {}
for i in range(days):
forecast_date = start_date + timedelta(days=i)
# 简化的需求预测
# 在生产环境中,将使用机器学习模型
base_demand = 70.0 # 70% 基础入住率
# 星期几因子
if forecast_date.weekday() in [4, 5]: # 周末
day_factor = 15
elif forecast_date.weekday() == 6:
day_factor = -10
else:
day_factor = 0
# 季节性因子(简化)
month = forecast_date.month
if month in [6, 7, 8]: # 夏季
season_factor = 10
elif month in [12, 1]: # 假日季节
season_factor = 15
else:
season_factor = 0
forecasted_occupancy = base_demand + day_factor + season_factor
forecasted_occupancy = min(100, max(0, forecasted_occupancy))
forecast[forecast_date.isoformat()] = {
'date': forecast_date.isoformat(),
'forecasted_occupancy': forecasted_occupancy,
'confidence': 'high' if i < 14 else 'medium' if i < 30 else 'low'
}
return forecast
def optimize_inventory(self, total_rooms: int, date_range: tuple) -> dict:
"""优化客房库存分配"""
# 在不同渠道间分配房间
# 直接预订、OTA、公司合约、等。
allocation = {
'direct': int(total_rooms * 0.40), # 40% 直接
'ota': int(total_rooms * 0.35), # 35% OTA
'corporate': int(total_rooms * 0.15), # 15% 公司
'walk_in': int(total_rooms * 0.10) # 10% 散客
}
return {
'total_rooms': total_rooms,
'allocation': allocation,
'date_range': {
'start': date_range[0].isoformat(),
'end': date_range[1].isoformat()
}
}
def calculate_revpar(self, revenue: Decimal, available_rooms: int) -> Decimal:
"""计算每间可用客房收入"""
if available_rooms == 0:
return Decimal('0')
revpar = revenue / available_rooms
return revpar.quantize(Decimal('0.01'))
def calculate_adr(self, revenue: Decimal, rooms_sold: int) -> Decimal:
"""计算平均每日房价"""
if rooms_sold == 0:
return Decimal('0')
adr = revenue / rooms_sold
return adr.quantize(Decimal('0.01'))
@dataclass
class GuestRequest:
"""宾客服务请求"""
request_id: str
reservation_id: str
room_number: str
guest_name: str
request_type: str # 'housekeeping', 'maintenance', 'concierge', 'amenity'
description: str
priority: str # 'low', 'medium', 'high'
status: str # 'open', 'in_progress', 'completed'
created_at: datetime
assigned_to: Optional[str]
completed_at: Optional[datetime]
class GuestServicesSystem:
"""宾客服务和体验管理"""
def __init__(self):
self.requests = []
self.guest_preferences = {}
self.loyalty_members = {}
def submit_guest_request(self, request_data: dict) -> GuestRequest:
"""提交宾客服务请求"""
request = GuestRequest(
request_id=self._generate_request_id(),
reservation_id=request_data['reservation_id'],
room_number=request_data['room_number'],
guest_name=request_data['guest_name'],
request_type=request_data['request_type'],
description=request_data['description'],
priority=request_data.get('priority', 'medium'),
status='open',
created_at=datetime.now(),
assigned_to=None,
completed_at=None
)
self.requests.append(request)
# 基于请求类型自动分配
self._auto_assign_request(request)
return request
def track_guest_preferences(self, guest_id: str, preferences: dict):
"""追踪宾客偏好以实现个性化"""
self.guest_preferences[guest_id] = {
'room_preferences': {
'floor': preferences.get('preferred_floor'),
'bed_type': preferences.get('bed_type'),
'view': preferences.get('view_preference')
},
'amenities': preferences.get('amenities', []),
'dietary_restrictions': preferences.get('dietary_restrictions', []),
'special_occasions': preferences.get('special_occasions', {}),
'communication_preference': preferences.get('communication', 'email')
}
def calculate_guest_satisfaction_score(self, reservation_id: str) -> dict:
"""计算宾客满意度指标"""
# 模拟宾客满意度分数
# 在生产环境中,将基于调查和反馈
metrics = {
'overall_satisfaction': 4.5, # 满分 5 分
'check_in_experience': 4.7,
'room_quality': 4.3,
'staff_friendliness': 4.8,
'cleanliness': 4.6,
'value_for_money': 4.2,
'likelihood_to_recommend': 9.0 # NPS 分数 (0-10)
}
return {
'reservation_id': reservation_id,
'satisfaction_metrics': metrics,
'nps_category': 'promoter' if metrics['likelihood_to_recommend'] >= 9 else
'passive' if metrics['likelihood_to_recommend'] >= 7 else
'detractor'
}
def _auto_assign_request(self, request: GuestRequest):
"""自动将请求分配给员工"""
# 将实现智能分配逻辑
assignments = {
'housekeeping': 'housekeeping_team',
'maintenance': 'maintenance_team',
'concierge': 'concierge_team',
'amenity': 'front_desk'
}
request.assigned_to = assignments.get(request.request_type, 'front_desk')
def _generate_request_id(self) -> str:
import uuid
return f"REQ-{uuid.uuid4().hex[:8].upper()}"
❌ 手动预订管理 ❌ 全年静态定价 ❌ 无宾客偏好追踪 ❌ 渠道管理不善 ❌ 对宾客请求响应缓慢 ❌ 无移动功能 ❌ 员工培训不足 ❌ 数据安全性差 ❌ 无收益分析
每周安装次数
77
代码仓库
GitHub 星标数
11
首次出现
2026年1月24日
安全审计
安装于
opencode68
codex67
gemini-cli66
cursor63
github-copilot61
amp57
Expert guidance for hotel management, reservation systems, property management systems (PMS), guest services, revenue management, and hospitality technology solutions.
from dataclasses import dataclass
from datetime import datetime, timedelta, date
from typing import List, Optional, Dict
from decimal import Decimal
from enum import Enum
class RoomType(Enum):
STANDARD = "standard"
DELUXE = "deluxe"
SUITE = "suite"
EXECUTIVE = "executive"
class RoomStatus(Enum):
VACANT_CLEAN = "vacant_clean"
VACANT_DIRTY = "vacant_dirty"
OCCUPIED_CLEAN = "occupied_clean"
OCCUPIED_DIRTY = "occupied_dirty"
OUT_OF_ORDER = "out_of_order"
OUT_OF_SERVICE = "out_of_service"
class ReservationStatus(Enum):
CONFIRMED = "confirmed"
CHECKED_IN = "checked_in"
CHECKED_OUT = "checked_out"
CANCELLED = "cancelled"
NO_SHOW = "no_show"
@dataclass
class Room:
"""Hotel room information"""
room_number: str
room_type: RoomType
floor: int
status: RoomStatus
base_rate: Decimal
features: List[str]
bed_type: str
max_occupancy: int
square_feet: int
is_smoking: bool
@dataclass
class Reservation:
"""Guest reservation"""
reservation_id: str
guest_name: str
guest_email: str
guest_phone: str
room_type: RoomType
check_in_date: date
check_out_date: date
num_adults: int
num_children: int
status: ReservationStatus
rate_per_night: Decimal
total_amount: Decimal
special_requests: str
created_at: datetime
booking_source: str # 'direct', 'ota', 'phone', etc.
assigned_room: Optional[str]
@dataclass
class Folio:
"""Guest folio (bill)"""
folio_id: str
reservation_id: str
room_number: str
guest_name: str
charges: List[Dict]
total_charges: Decimal
payments: List[Dict]
balance: Decimal
class PropertyManagementSystem:
"""Hotel property management system"""
def __init__(self):
self.rooms = {}
self.reservations = {}
self.folios = {}
self.guests = {}
def create_reservation(self, reservation_data: dict) -> Reservation:
"""Create new reservation"""
reservation_id = self._generate_reservation_id()
# Calculate total amount
check_in = reservation_data['check_in_date']
check_out = reservation_data['check_out_date']
num_nights = (check_out - check_in).days
rate_per_night = Decimal(str(reservation_data['rate_per_night']))
total_amount = rate_per_night * num_nights
reservation = Reservation(
reservation_id=reservation_id,
guest_name=reservation_data['guest_name'],
guest_email=reservation_data['guest_email'],
guest_phone=reservation_data['guest_phone'],
room_type=RoomType(reservation_data['room_type']),
check_in_date=check_in,
check_out_date=check_out,
num_adults=reservation_data['num_adults'],
num_children=reservation_data.get('num_children', 0),
status=ReservationStatus.CONFIRMED,
rate_per_night=rate_per_night,
total_amount=total_amount,
special_requests=reservation_data.get('special_requests', ''),
created_at=datetime.now(),
booking_source=reservation_data.get('booking_source', 'direct'),
assigned_room=None
)
self.reservations[reservation_id] = reservation
return reservation
def check_in_guest(self, reservation_id: str) -> dict:
"""Process guest check-in"""
reservation = self.reservations.get(reservation_id)
if not reservation:
return {'error': 'Reservation not found'}
# Find available room of requested type
available_room = self._find_available_room(
reservation.room_type,
reservation.check_in_date,
reservation.check_out_date
)
if not available_room:
return {'error': 'No rooms available of requested type'}
# Assign room
reservation.assigned_room = available_room.room_number
reservation.status = ReservationStatus.CHECKED_IN
# Update room status
available_room.status = RoomStatus.OCCUPIED_CLEAN
# Create folio
folio = self._create_folio(reservation, available_room)
return {
'reservation_id': reservation_id,
'room_number': available_room.room_number,
'guest_name': reservation.guest_name,
'check_in_time': datetime.now().isoformat(),
'check_out_date': reservation.check_out_date.isoformat(),
'folio_id': folio.folio_id
}
def check_out_guest(self, reservation_id: str) -> dict:
"""Process guest check-out"""
reservation = self.reservations.get(reservation_id)
if not reservation:
return {'error': 'Reservation not found'}
# Get folio
folio = next(
(f for f in self.folios.values() if f.reservation_id == reservation_id),
None
)
if not folio:
return {'error': 'Folio not found'}
# Check for outstanding balance
if folio.balance > 0:
return {
'error': 'Outstanding balance',
'balance_due': float(folio.balance)
}
# Update reservation status
reservation.status = ReservationStatus.CHECKED_OUT
# Update room status
if reservation.assigned_room:
room = self.rooms.get(reservation.assigned_room)
if room:
room.status = RoomStatus.VACANT_DIRTY
return {
'reservation_id': reservation_id,
'guest_name': reservation.guest_name,
'check_out_time': datetime.now().isoformat(),
'total_charges': float(folio.total_charges),
'folio_summary': {
'room_charges': float(folio.total_charges),
'payments_received': float(folio.total_charges - folio.balance)
}
}
def _find_available_room(self,
room_type: RoomType,
check_in: date,
check_out: date) -> Optional[Room]:
"""Find available room of specified type"""
for room in self.rooms.values():
if room.room_type != room_type:
continue
if room.status not in [RoomStatus.VACANT_CLEAN, RoomStatus.VACANT_DIRTY]:
continue
# Check if room is available for date range
if self._is_room_available(room.room_number, check_in, check_out):
return room
return None
def _is_room_available(self, room_number: str, check_in: date, check_out: date) -> bool:
"""Check if room is available for date range"""
for reservation in self.reservations.values():
if reservation.assigned_room != room_number:
continue
if reservation.status in [ReservationStatus.CANCELLED, ReservationStatus.NO_SHOW]:
continue
# Check for date overlap
if not (check_out <= reservation.check_in_date or check_in >= reservation.check_out_date):
return False
return True
def _create_folio(self, reservation: Reservation, room: Room) -> Folio:
"""Create guest folio"""
folio_id = self._generate_folio_id()
# Calculate room charges
num_nights = (reservation.check_out_date - reservation.check_in_date).days
room_charge = reservation.rate_per_night * num_nights
charges = [{
'date': datetime.now(),
'description': f'Room {room.room_number} - {num_nights} nights',
'amount': float(room_charge)
}]
folio = Folio(
folio_id=folio_id,
reservation_id=reservation.reservation_id,
room_number=room.room_number,
guest_name=reservation.guest_name,
charges=charges,
total_charges=room_charge,
payments=[],
balance=room_charge
)
self.folios[folio_id] = folio
return folio
def post_charge(self, folio_id: str, charge_data: dict) -> dict:
"""Post charge to guest folio"""
folio = self.folios.get(folio_id)
if not folio:
return {'error': 'Folio not found'}
charge = {
'date': datetime.now(),
'description': charge_data['description'],
'amount': float(Decimal(str(charge_data['amount'])))
}
folio.charges.append(charge)
folio.total_charges += Decimal(str(charge_data['amount']))
folio.balance += Decimal(str(charge_data['amount']))
return {
'folio_id': folio_id,
'charge_posted': charge,
'new_balance': float(folio.balance)
}
def process_payment(self, folio_id: str, payment_data: dict) -> dict:
"""Process payment for folio"""
folio = self.folios.get(folio_id)
if not folio:
return {'error': 'Folio not found'}
payment_amount = Decimal(str(payment_data['amount']))
if payment_amount > folio.balance:
return {'error': 'Payment exceeds balance'}
payment = {
'date': datetime.now(),
'payment_method': payment_data['payment_method'],
'amount': float(payment_amount)
}
folio.payments.append(payment)
folio.balance -= payment_amount
return {
'folio_id': folio_id,
'payment_processed': payment,
'remaining_balance': float(folio.balance)
}
def get_room_availability(self, check_in: date, check_out: date) -> dict:
"""Get room availability for date range"""
availability = {}
for room_type in RoomType:
available_count = 0
for room in self.rooms.values():
if room.room_type == room_type:
if self._is_room_available(room.room_number, check_in, check_out):
available_count += 1
availability[room_type.value] = available_count
return {
'check_in_date': check_in.isoformat(),
'check_out_date': check_out.isoformat(),
'availability': availability
}
def _generate_reservation_id(self) -> str:
import uuid
return f"RES-{uuid.uuid4().hex[:10].upper()}"
def _generate_folio_id(self) -> str:
import uuid
return f"FOL-{uuid.uuid4().hex[:8].upper()}"
import numpy as np
class RevenueManagementSystem:
"""Hotel revenue management and dynamic pricing"""
def __init__(self):
self.pricing_rules = []
self.demand_forecast = {}
def calculate_dynamic_rate(self,
room_type: RoomType,
check_in_date: date,
days_until_arrival: int,
current_occupancy: float,
historical_data: dict) -> Decimal:
"""Calculate dynamic room rate"""
# Base rate
base_rates = {
RoomType.STANDARD: Decimal('150'),
RoomType.DELUXE: Decimal('200'),
RoomType.SUITE: Decimal('350'),
RoomType.EXECUTIVE: Decimal('450')
}
base_rate = base_rates.get(room_type, Decimal('150'))
# Demand multiplier based on occupancy
if current_occupancy > 0.85:
demand_multiplier = Decimal('1.30') # High demand
elif current_occupancy > 0.70:
demand_multiplier = Decimal('1.15') # Moderate demand
elif current_occupancy > 0.50:
demand_multiplier = Decimal('1.00') # Normal
else:
demand_multiplier = Decimal('0.85') # Low demand
# Booking window multiplier
if days_until_arrival < 7:
window_multiplier = Decimal('1.20') # Last minute
elif days_until_arrival < 14:
window_multiplier = Decimal('1.10')
elif days_until_arrival > 60:
window_multiplier = Decimal('0.90') # Early bird
else:
window_multiplier = Decimal('1.00')
# Day of week adjustment
if check_in_date.weekday() in [4, 5]: # Friday, Saturday
day_multiplier = Decimal('1.25')
elif check_in_date.weekday() == 6: # Sunday
day_multiplier = Decimal('0.95')
else:
day_multiplier = Decimal('1.00')
# Calculate final rate
dynamic_rate = base_rate * demand_multiplier * window_multiplier * day_multiplier
# Round to nearest dollar
dynamic_rate = dynamic_rate.quantize(Decimal('1'))
return dynamic_rate
def forecast_demand(self, start_date: date, days: int) -> dict:
"""Forecast demand for upcoming period"""
forecast = {}
for i in range(days):
forecast_date = start_date + timedelta(days=i)
# Simplified demand forecast
# In production, would use ML models
base_demand = 70.0 # 70% base occupancy
# Day of week factor
if forecast_date.weekday() in [4, 5]: # Weekend
day_factor = 15
elif forecast_date.weekday() == 6:
day_factor = -10
else:
day_factor = 0
# Seasonality factor (simplified)
month = forecast_date.month
if month in [6, 7, 8]: # Summer
season_factor = 10
elif month in [12, 1]: # Holiday season
season_factor = 15
else:
season_factor = 0
forecasted_occupancy = base_demand + day_factor + season_factor
forecasted_occupancy = min(100, max(0, forecasted_occupancy))
forecast[forecast_date.isoformat()] = {
'date': forecast_date.isoformat(),
'forecasted_occupancy': forecasted_occupancy,
'confidence': 'high' if i < 14 else 'medium' if i < 30 else 'low'
}
return forecast
def optimize_inventory(self, total_rooms: int, date_range: tuple) -> dict:
"""Optimize room inventory allocation"""
# Allocate rooms across different channels
# Direct bookings, OTAs, corporate contracts, etc.
allocation = {
'direct': int(total_rooms * 0.40), # 40% direct
'ota': int(total_rooms * 0.35), # 35% OTAs
'corporate': int(total_rooms * 0.15), # 15% corporate
'walk_in': int(total_rooms * 0.10) # 10% walk-ins
}
return {
'total_rooms': total_rooms,
'allocation': allocation,
'date_range': {
'start': date_range[0].isoformat(),
'end': date_range[1].isoformat()
}
}
def calculate_revpar(self, revenue: Decimal, available_rooms: int) -> Decimal:
"""Calculate Revenue Per Available Room"""
if available_rooms == 0:
return Decimal('0')
revpar = revenue / available_rooms
return revpar.quantize(Decimal('0.01'))
def calculate_adr(self, revenue: Decimal, rooms_sold: int) -> Decimal:
"""Calculate Average Daily Rate"""
if rooms_sold == 0:
return Decimal('0')
adr = revenue / rooms_sold
return adr.quantize(Decimal('0.01'))
@dataclass
class GuestRequest:
"""Guest service request"""
request_id: str
reservation_id: str
room_number: str
guest_name: str
request_type: str # 'housekeeping', 'maintenance', 'concierge', 'amenity'
description: str
priority: str # 'low', 'medium', 'high'
status: str # 'open', 'in_progress', 'completed'
created_at: datetime
assigned_to: Optional[str]
completed_at: Optional[datetime]
class GuestServicesSystem:
"""Guest services and experience management"""
def __init__(self):
self.requests = []
self.guest_preferences = {}
self.loyalty_members = {}
def submit_guest_request(self, request_data: dict) -> GuestRequest:
"""Submit guest service request"""
request = GuestRequest(
request_id=self._generate_request_id(),
reservation_id=request_data['reservation_id'],
room_number=request_data['room_number'],
guest_name=request_data['guest_name'],
request_type=request_data['request_type'],
description=request_data['description'],
priority=request_data.get('priority', 'medium'),
status='open',
created_at=datetime.now(),
assigned_to=None,
completed_at=None
)
self.requests.append(request)
# Auto-assign based on request type
self._auto_assign_request(request)
return request
def track_guest_preferences(self, guest_id: str, preferences: dict):
"""Track guest preferences for personalization"""
self.guest_preferences[guest_id] = {
'room_preferences': {
'floor': preferences.get('preferred_floor'),
'bed_type': preferences.get('bed_type'),
'view': preferences.get('view_preference')
},
'amenities': preferences.get('amenities', []),
'dietary_restrictions': preferences.get('dietary_restrictions', []),
'special_occasions': preferences.get('special_occasions', {}),
'communication_preference': preferences.get('communication', 'email')
}
def calculate_guest_satisfaction_score(self, reservation_id: str) -> dict:
"""Calculate guest satisfaction metrics"""
# Simulate guest satisfaction score
# In production, would be based on surveys and feedback
metrics = {
'overall_satisfaction': 4.5, # Out of 5
'check_in_experience': 4.7,
'room_quality': 4.3,
'staff_friendliness': 4.8,
'cleanliness': 4.6,
'value_for_money': 4.2,
'likelihood_to_recommend': 9.0 # NPS score (0-10)
}
return {
'reservation_id': reservation_id,
'satisfaction_metrics': metrics,
'nps_category': 'promoter' if metrics['likelihood_to_recommend'] >= 9 else
'passive' if metrics['likelihood_to_recommend'] >= 7 else
'detractor'
}
def _auto_assign_request(self, request: GuestRequest):
"""Auto-assign request to staff"""
# Would implement smart assignment logic
assignments = {
'housekeeping': 'housekeeping_team',
'maintenance': 'maintenance_team',
'concierge': 'concierge_team',
'amenity': 'front_desk'
}
request.assigned_to = assignments.get(request.request_type, 'front_desk')
def _generate_request_id(self) -> str:
import uuid
return f"REQ-{uuid.uuid4().hex[:8].upper()}"
❌ Manual reservation management ❌ Static pricing year-round ❌ No guest preference tracking ❌ Poor channel management ❌ Slow response to guest requests ❌ No mobile capabilities ❌ Inadequate staff training ❌ Poor data security ❌ No revenue analytics
Weekly Installs
77
Repository
GitHub Stars
11
First Seen
Jan 24, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode68
codex67
gemini-cli66
cursor63
github-copilot61
amp57
EnergyKit iOS 开发指南:Swift 6.2 电网电力预测与负载管理
621 周安装