Срочные улучшения: проверка занятости слота, автоочистка cancelled записей
This commit is contained in:
+23
-4
@@ -10,7 +10,9 @@ from app.states.booking import BookingState
|
|||||||
from app.services.booking_service import (
|
from app.services.booking_service import (
|
||||||
create_booking,
|
create_booking,
|
||||||
update_booking,
|
update_booking,
|
||||||
get_busy_times
|
get_busy_times,
|
||||||
|
is_slot_busy,
|
||||||
|
cleanup_cancelled
|
||||||
)
|
)
|
||||||
from app.keyboards.menu import menu, cancel_menu
|
from app.keyboards.menu import menu, cancel_menu
|
||||||
from app.keyboards.calendar import get_dates_keyboard
|
from app.keyboards.calendar import get_dates_keyboard
|
||||||
@@ -210,14 +212,31 @@ async def confirm_booking_callback(
|
|||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
||||||
|
# Check if slot is already taken
|
||||||
|
master = data.get('master', '?')
|
||||||
|
date = data.get('date', '?')
|
||||||
|
time = data.get('time', '?')
|
||||||
|
|
||||||
|
if await is_slot_busy(master, date, time):
|
||||||
|
logger.warning("Slot already busy: {mst} {dt} {tm}", mst=master, dt=date, tm=time)
|
||||||
|
await callback.message.edit_text(
|
||||||
|
"❌ Это время уже занято. Пожалуйста, выберите другое время."
|
||||||
|
)
|
||||||
|
await state.clear()
|
||||||
|
await callback.answer()
|
||||||
|
return
|
||||||
|
|
||||||
await create_booking(
|
await create_booking(
|
||||||
user_id=callback.from_user.id,
|
user_id=callback.from_user.id,
|
||||||
service=data.get('service', '?'),
|
service=data.get('service', '?'),
|
||||||
master=data.get('master', '?'),
|
master=master,
|
||||||
date=data.get('date', '?'),
|
date=date,
|
||||||
time=data.get('time', '?')
|
time=time
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Clean up old cancelled bookings
|
||||||
|
cleanup_cancelled()
|
||||||
|
|
||||||
result_text = "✅ Запись успешно создана"
|
result_text = "✅ Запись успешно создана"
|
||||||
|
|
||||||
await state.clear()
|
await state.clear()
|
||||||
|
|||||||
@@ -4,7 +4,11 @@ from app.db.memory import (
|
|||||||
get_user_bookings as db_get_user_bookings,
|
get_user_bookings as db_get_user_bookings,
|
||||||
cancel_booking as db_cancel_booking,
|
cancel_booking as db_cancel_booking,
|
||||||
update_booking as db_update_booking,
|
update_booking as db_update_booking,
|
||||||
|
load_bookings as db_load_bookings,
|
||||||
|
save_bookings as db_save_bookings,
|
||||||
|
BOOKINGS_FILE,
|
||||||
)
|
)
|
||||||
|
from app.logger import logger
|
||||||
|
|
||||||
|
|
||||||
async def create_booking(user_id, service, master, date, time):
|
async def create_booking(user_id, service, master, date, time):
|
||||||
@@ -25,3 +29,36 @@ async def cancel_booking(booking_id):
|
|||||||
|
|
||||||
async def update_booking(booking_id, service, master, date, time):
|
async def update_booking(booking_id, service, master, date, time):
|
||||||
return db_update_booking(booking_id, service, master, date, time)
|
return db_update_booking(booking_id, service, master, date, time)
|
||||||
|
|
||||||
|
|
||||||
|
async def is_slot_busy(master, date, time):
|
||||||
|
"""Check if a time slot is already taken by an active booking."""
|
||||||
|
busy = db_get_busy_times(master, date)
|
||||||
|
return time in busy
|
||||||
|
|
||||||
|
|
||||||
|
def cleanup_cancelled():
|
||||||
|
"""Remove cancelled bookings older than the head (keep only last 5 cancelled per user)."""
|
||||||
|
bookings = db_load_bookings()
|
||||||
|
active = [b for b in bookings if b["status"] == "active"]
|
||||||
|
cancelled = [b for b in bookings if b["status"] == "cancelled"]
|
||||||
|
|
||||||
|
# Group cancelled by user, keep last 5 per user
|
||||||
|
from collections import defaultdict
|
||||||
|
by_user = defaultdict(list)
|
||||||
|
for b in cancelled:
|
||||||
|
by_user[b["user_id"]].append(b)
|
||||||
|
|
||||||
|
keep_ids = set()
|
||||||
|
for uid, user_cancel in by_user.items():
|
||||||
|
# Keep the 5 most recent
|
||||||
|
user_cancel.sort(key=lambda x: x.get("id", 0), reverse=True)
|
||||||
|
for b in user_cancel[:5]:
|
||||||
|
keep_ids.add(b["id"])
|
||||||
|
|
||||||
|
# Rebuild: keep active + keep recent cancelled
|
||||||
|
bookings = active + [b for b in cancelled if b["id"] in keep_ids]
|
||||||
|
db_save_bookings(bookings)
|
||||||
|
removed = len(cancelled) - len(keep_ids)
|
||||||
|
if removed > 0:
|
||||||
|
logger.info("Cleaned up {n} old cancelled bookings", n=removed)
|
||||||
|
|||||||
Reference in New Issue
Block a user