hospitality-expert

Expert guidance for hotel management, reservation systems, property management systems (PMS), guest services, revenue management, and hospitality technology solutions.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "hospitality-expert" with this command: npx skills add personamanagmentlayer/pcl/personamanagmentlayer-pcl-hospitality-expert

Hospitality Expert

Expert guidance for hotel management, reservation systems, property management systems (PMS), guest services, revenue management, and hospitality technology solutions.

Core Concepts

Hotel Management Systems

  • Property Management System (PMS)

  • Central Reservation System (CRS)

  • Revenue Management System (RMS)

  • Channel Manager

  • Point of Sale (POS)

  • Guest Relationship Management (GRM)

  • Housekeeping management

Technologies

  • Mobile check-in/check-out

  • Digital key systems

  • Guest messaging platforms

  • IoT for room automation

  • AI chatbots for customer service

  • Contactless payments

  • Energy management systems

Standards and Protocols

  • HTNG (Hotel Technology Next Generation)

  • OpenTravel Alliance standards

  • PCI-DSS for payment security

  • ADA compliance for accessibility

  • Brand standards (if franchise)

  • OTA integrations (Booking.com, Expedia)

Property Management System

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()}"

Revenue Management System

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'))

Guest Services Management

@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()}"

Best Practices

Reservations Management

  • Implement real-time availability

  • Use channel manager for distribution

  • Enable mobile booking

  • Implement flexible cancellation policies

  • Send automated confirmations

  • Track booking sources

  • Enable group bookings

Revenue Management

  • Implement dynamic pricing

  • Monitor competitor rates

  • Forecast demand accurately

  • Optimize inventory allocation

  • Track RevPAR and ADR

  • Use yield management strategies

  • Analyze booking patterns

Guest Experience

  • Personalize guest interactions

  • Enable mobile check-in/out

  • Provide digital concierge services

  • Track guest preferences

  • Respond promptly to requests

  • Implement loyalty programs

  • Gather feedback systematically

Operations

  • Maintain housekeeping efficiency

  • Implement preventive maintenance

  • Use automated messaging

  • Monitor room status in real-time

  • Optimize staff scheduling

  • Track operational metrics

  • Ensure PCI-DSS compliance

Anti-Patterns

❌ 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

Resources

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

finance-expert

No summary provided by upstream source.

Repository SourceNeeds Review
General

trading-expert

No summary provided by upstream source.

Repository SourceNeeds Review
General

dart-expert

No summary provided by upstream source.

Repository SourceNeeds Review
General

postgresql-expert

No summary provided by upstream source.

Repository SourceNeeds Review