Venus / src /ui /reservations_ui.py
Amir
Venus Hotel Front Desk – initial HF deploy
9d9d2a1
import gradio as gr
from src.utils.time_utils import muscat_date_str
from src.services.reservation_service import list_active, check_in, check_out
from src.services.room_service import room_detail
from src.services.pricing_service import compute_rate_float
def render_reservations_tab(db_path: str, auth_state: gr.State):
with gr.Column() as panel:
gr.Markdown("## Reservations")
active_table = gr.Dataframe(
headers=["id","room_no","room_type","guest_name","guest_phone","check_in_date","check_out_date","nights","rate_ro","total_ro","status"],
interactive=False,
row_count=10,
col_count=11,
)
refresh = gr.Button("Refresh Active Reservations")
gr.Markdown("### Check-in (creates reservation and sets room to occupied)")
room_no = gr.Number(label="Room number", precision=0)
guest_name = gr.Textbox(label="Guest name")
guest_phone = gr.Textbox(label="Phone")
check_in_date = gr.Textbox(label="Check-in date (YYYY-MM-DD)", value=muscat_date_str())
check_out_date = gr.Textbox(label="Check-out date (YYYY-MM-DD)", value=muscat_date_str())
rate_ro = gr.Number(label="Rate (auto suggested below)", value=0)
note = gr.Textbox(label="Mandatory note", lines=2)
suggest_btn = gr.Button("Suggest Rate From Room (problems/pricing)")
create_btn = gr.Button("Check-in", variant="primary")
msg = gr.Markdown("")
gr.Markdown("### Check-out (closes reservation and sets room to need_cleaning)")
res_id = gr.Number(label="Reservation ID", precision=0)
close_note = gr.Textbox(label="Mandatory note", lines=2)
close_btn = gr.Button("Check-out", variant="primary")
close_msg = gr.Markdown("")
def _refresh(auth):
if not auth:
return []
rows = list_active(db_path)
return [[
r["id"], r["room_no"], r["room_type"], r["guest_name"], r["guest_phone"],
r["check_in_date"], r["check_out_date"], r["nights"], r["rate_ro"], r["total_ro"], r["status"]
] for r in rows]
def _suggest(room_no_val, auth):
if not auth:
return 0, "❌ Please login."
rn = int(room_no_val or 0)
if rn <= 0:
return 0, "❌ Enter valid room number."
room, probs, _ = room_detail(db_path, rn)
if not room:
return 0, "❌ Room not found."
has_problem = bool(probs)
rate = compute_rate_float(room["room_type"], room["sellable"], room["status"], has_problem)
if rate <= 0:
return 0, f"⚠️ No sellable rate for this room (type/status/sellable)."
return rate, f"βœ… Suggested rate: {rate:.3f} RO"
def _checkin(rn, g, ph, ci, co, rate, note_text, auth):
if not auth:
return "❌ Please login."
rn = int(rn or 0)
if rn <= 0:
return "❌ Invalid room number."
if not g.strip() or not ph.strip():
return "❌ Guest name and phone required."
if not note_text or not note_text.strip():
return "❌ Note required."
if float(rate or 0) <= 0:
return "❌ Rate must be > 0."
rid = check_in(db_path, rn, g.strip(), ph.strip(), ci.strip(), co.strip(), float(rate), note_text.strip(), auth["username"])
return f"βœ… Checked-in. Reservation ID: **{rid}**"
def _checkout(reservation_id, note_text, auth):
if not auth:
return "❌ Please login."
rid = int(reservation_id or 0)
if rid <= 0:
return "❌ Invalid reservation id."
if not note_text or not note_text.strip():
return "❌ Note required."
check_out(db_path, rid, note_text.strip(), auth["username"])
return "βœ… Checked-out."
refresh.click(_refresh, inputs=[auth_state], outputs=[active_table])
panel.load(_refresh, inputs=[auth_state], outputs=[active_table])
suggest_btn.click(_suggest, inputs=[room_no, auth_state], outputs=[rate_ro, msg])
create_btn.click(_checkin, inputs=[room_no, guest_name, guest_phone, check_in_date, check_out_date, rate_ro, note, auth_state], outputs=[msg]).then(
_refresh, inputs=[auth_state], outputs=[active_table]
)
close_btn.click(_checkout, inputs=[res_id, close_note, auth_state], outputs=[close_msg]).then(
_refresh, inputs=[auth_state], outputs=[active_table]
)
return panel, {}