hotelutils 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- hotelutils/__init__.py +17 -0
- hotelutils/apps.py +5 -0
- hotelutils/utils.py +111 -0
- hotelutils-0.1.0.dist-info/METADATA +11 -0
- hotelutils-0.1.0.dist-info/RECORD +7 -0
- hotelutils-0.1.0.dist-info/WHEEL +5 -0
- hotelutils-0.1.0.dist-info/top_level.txt +1 -0
hotelutils/__init__.py
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from .utils import (
|
|
2
|
+
generate_booking_reference,
|
|
3
|
+
calculate_dynamic_price,
|
|
4
|
+
calculate_loyalty_points,
|
|
5
|
+
calculate_cleaning_duration,
|
|
6
|
+
estimate_room_availability,
|
|
7
|
+
generate_invoice_number,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"generate_booking_reference",
|
|
12
|
+
"calculate_dynamic_price",
|
|
13
|
+
"calculate_loyalty_points",
|
|
14
|
+
"calculate_cleaning_duration",
|
|
15
|
+
"estimate_room_availability",
|
|
16
|
+
"generate_invoice_number",
|
|
17
|
+
]
|
hotelutils/apps.py
ADDED
hotelutils/utils.py
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import random
|
|
2
|
+
import string
|
|
3
|
+
from datetime import datetime, date
|
|
4
|
+
|
|
5
|
+
def generate_booking_reference(guest_name: str, room_type: str) -> str:
|
|
6
|
+
"""
|
|
7
|
+
Generates a unique booking reference.
|
|
8
|
+
Example: SH-SMI-DEL-8FA2
|
|
9
|
+
"""
|
|
10
|
+
clean_name = "".join(c for c in guest_name if c.isalnum()).upper()
|
|
11
|
+
name_part = clean_name[:3] if len(clean_name) >= 3 else (clean_name + "XXX")[:3]
|
|
12
|
+
|
|
13
|
+
clean_room = "".join(c for c in room_type if c.isalnum()).upper()
|
|
14
|
+
room_part = clean_room[:3] if len(clean_room) >= 3 else (clean_room + "XXX")[:3]
|
|
15
|
+
|
|
16
|
+
rand_part = "".join(random.choices(string.ascii_uppercase + string.digits, k=4))
|
|
17
|
+
|
|
18
|
+
return f"SH-{name_part}-{room_part}-{rand_part}"
|
|
19
|
+
|
|
20
|
+
def calculate_dynamic_price(base_price: float, demand_factor: float, days_ahead: int) -> float:
|
|
21
|
+
"""
|
|
22
|
+
Calculates dynamic price based on base price, demand factor (occupancy index 0.0 - 2.0),
|
|
23
|
+
and days ahead of check-in.
|
|
24
|
+
- Higher demand_factor increases price.
|
|
25
|
+
- Booking last-minute (days_ahead <= 3) increases price by up to 20% if demand is high.
|
|
26
|
+
- Booking far in advance (days_ahead > 30) offers up to a 10% discount.
|
|
27
|
+
"""
|
|
28
|
+
# Clamp demand factor between 0.5 and 2.0
|
|
29
|
+
demand_factor = max(0.5, min(2.0, demand_factor))
|
|
30
|
+
|
|
31
|
+
# Calculate days-ahead modifier
|
|
32
|
+
if days_ahead <= 3:
|
|
33
|
+
time_modifier = 1.2 # 20% premium for last-minute
|
|
34
|
+
elif days_ahead > 30:
|
|
35
|
+
time_modifier = 0.9 # 10% advance discount
|
|
36
|
+
else:
|
|
37
|
+
time_modifier = 1.0
|
|
38
|
+
|
|
39
|
+
final_price = base_price * demand_factor * time_modifier
|
|
40
|
+
return round(final_price, 2)
|
|
41
|
+
|
|
42
|
+
def calculate_loyalty_points(booking_total_usd: float, user_tier: str) -> int:
|
|
43
|
+
"""
|
|
44
|
+
Calculates loyalty points based on booking cost and member tier.
|
|
45
|
+
Tiers: regular (1x), bronze (1.2x), silver (1.5x), gold (2.0x)
|
|
46
|
+
"""
|
|
47
|
+
tier_multipliers = {
|
|
48
|
+
"regular": 1.0,
|
|
49
|
+
"bronze": 1.2,
|
|
50
|
+
"silver": 1.5,
|
|
51
|
+
"gold": 2.0
|
|
52
|
+
}
|
|
53
|
+
multiplier = tier_multipliers.get(user_tier.lower(), 1.0)
|
|
54
|
+
points = float(booking_total_usd) * multiplier
|
|
55
|
+
return int(points)
|
|
56
|
+
|
|
57
|
+
def calculate_cleaning_duration(room_type: str, status: str) -> int:
|
|
58
|
+
"""
|
|
59
|
+
Estimates cleaning duration in minutes.
|
|
60
|
+
Room types: suite (60 mins), deluxe (45 mins), standard (30 mins)
|
|
61
|
+
Multiplier based on dirty vs light cleaning status.
|
|
62
|
+
"""
|
|
63
|
+
base_durations = {
|
|
64
|
+
"suite": 60,
|
|
65
|
+
"deluxe": 45,
|
|
66
|
+
"standard": 30
|
|
67
|
+
}
|
|
68
|
+
base = base_durations.get(room_type.lower(), 30)
|
|
69
|
+
|
|
70
|
+
status_modifiers = {
|
|
71
|
+
"dirty": 1.2, # Needs thorough clean
|
|
72
|
+
"cleaning": 1.0,
|
|
73
|
+
"ready": 0.5 # Just touch-up/inspection
|
|
74
|
+
}
|
|
75
|
+
modifier = status_modifiers.get(status.lower(), 1.0)
|
|
76
|
+
return int(base * modifier)
|
|
77
|
+
|
|
78
|
+
def estimate_room_availability(target_range: tuple, existing_bookings: list) -> bool:
|
|
79
|
+
"""
|
|
80
|
+
Checks if a target date range (start_date, end_date) overlaps with any existing booking ranges.
|
|
81
|
+
target_range: (date/datetime, date/datetime)
|
|
82
|
+
existing_bookings: list of (start, end) tuples
|
|
83
|
+
Returns True if available (no overlap), False otherwise.
|
|
84
|
+
"""
|
|
85
|
+
target_start, target_end = target_range
|
|
86
|
+
# Normalize to date objects if they are datetime
|
|
87
|
+
if isinstance(target_start, datetime):
|
|
88
|
+
target_start = target_start.date()
|
|
89
|
+
if isinstance(target_end, datetime):
|
|
90
|
+
target_end = target_end.date()
|
|
91
|
+
|
|
92
|
+
for start, end in existing_bookings:
|
|
93
|
+
if isinstance(start, datetime):
|
|
94
|
+
start = start.date()
|
|
95
|
+
if isinstance(end, datetime):
|
|
96
|
+
end = end.date()
|
|
97
|
+
|
|
98
|
+
# Overlap condition: startA < endB and startB < endA
|
|
99
|
+
if target_start < end and start < target_end:
|
|
100
|
+
return False
|
|
101
|
+
|
|
102
|
+
return True
|
|
103
|
+
|
|
104
|
+
def generate_invoice_number(booking_id: int) -> str:
|
|
105
|
+
"""
|
|
106
|
+
Generates a unique invoice number.
|
|
107
|
+
Format: INV-YYYYMMDD-ID-RANDOM
|
|
108
|
+
"""
|
|
109
|
+
today_str = datetime.now().strftime("%Y%m%d")
|
|
110
|
+
rand_suffix = "".join(random.choices(string.ascii_uppercase + string.digits, k=3))
|
|
111
|
+
return f"INV-{today_str}-{booking_id}-{rand_suffix}"
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: hotelutils
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Custom utility package for Smart Hospitality Management System
|
|
5
|
+
Author: Meenakshi
|
|
6
|
+
Author-email: admin@smarthospitality.com
|
|
7
|
+
Requires-Python: >=3.9
|
|
8
|
+
Dynamic: author
|
|
9
|
+
Dynamic: author-email
|
|
10
|
+
Dynamic: requires-python
|
|
11
|
+
Dynamic: summary
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
hotelutils/__init__.py,sha256=HAJ_2YpHdwga_gl50kBSIVsztsfBCGemhSv0hR1EiMU,420
|
|
2
|
+
hotelutils/apps.py,sha256=mby04dBg7py4F_Jyk-5qLBbeKPw36PqYaWtt-EhxSv8,151
|
|
3
|
+
hotelutils/utils.py,sha256=YhxQkgkFFuuLWfsifO5a2Isvqi5CZ4kWbZ1TS1AgCLI,4063
|
|
4
|
+
hotelutils-0.1.0.dist-info/METADATA,sha256=k5HqiRFnOweGFXwZ2Huqd8ac4LWXc0v_0HAIx0OMUTI,288
|
|
5
|
+
hotelutils-0.1.0.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
|
|
6
|
+
hotelutils-0.1.0.dist-info/top_level.txt,sha256=TC_gs-6uJZnzwb8KE0NiZuntGrPo6NzX24SwQ7cpMhU,11
|
|
7
|
+
hotelutils-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
hotelutils
|