Реализация бронирования столиков ресторана на сайте

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Реализация бронирования столиков ресторана на сайте
Средняя
~5 рабочих дней
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    874
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    851

Реализация бронирования столиков ресторана на сайте

Бронирование столика — задача с несколькими нетривиальными деталями: вместимость стола должна совпадать с количеством гостей, ресторан работает по сменам (обед/ужин), а оверкинг (намеренная перепродажа) — иногда желаемое поведение.

Модель зала и столов

CREATE TABLE restaurant_halls (
    id          SERIAL PRIMARY KEY,
    name        VARCHAR(100),   -- 'Основной зал', 'Терраса', 'VIP'
    is_active   BOOLEAN DEFAULT TRUE
);

CREATE TABLE restaurant_tables (
    id              SERIAL PRIMARY KEY,
    hall_id         INTEGER REFERENCES restaurant_halls(id),
    table_number    VARCHAR(10),
    min_guests      SMALLINT DEFAULT 1,
    max_guests      SMALLINT NOT NULL,
    is_combinable   BOOLEAN DEFAULT FALSE,  -- можно ли сдвигать со смежными
    is_active       BOOLEAN DEFAULT TRUE
);

CREATE TABLE table_bookings (
    id              BIGSERIAL PRIMARY KEY,
    table_id        INTEGER REFERENCES restaurant_tables(id),
    guest_name      VARCHAR(255) NOT NULL,
    guest_phone     VARCHAR(50) NOT NULL,
    guest_email     VARCHAR(255),
    guests_count    SMALLINT NOT NULL,
    starts_at       TIMESTAMP NOT NULL,
    ends_at         TIMESTAMP NOT NULL,
    status          VARCHAR(20) DEFAULT 'pending',
    special_wishes  TEXT,
    deposit_paid    BOOLEAN DEFAULT FALSE,
    deposit_amount  NUMERIC(10,2),
    source          VARCHAR(30) DEFAULT 'website',  -- 'website','phone','walkin'
    created_at      TIMESTAMP DEFAULT NOW()
);

Смены и временны́е слоты

Ресторан не бронирует стол «на 15:37» — только на смену или фиксированный слот:

SHIFTS = {
    'lunch': {'start': time(12, 0), 'end': time(15, 0), 'duration': timedelta(hours=2)},
    'dinner': {'start': time(18, 0), 'end': time(23, 0), 'duration': timedelta(hours=2)},
}

def get_booking_slots(date: date) -> list[dict]:
    slots = []
    for shift_name, shift in SHIFTS.items():
        current = datetime.combine(date, shift['start'])
        end_dt = datetime.combine(date, shift['end'])
        while current + shift['duration'] <= end_dt:
            slots.append({
                'shift': shift_name,
                'starts_at': current,
                'ends_at': current + shift['duration'],
            })
            current += timedelta(hours=1)  # слоты каждый час
    return slots

Подбор стола по количеству гостей

def find_available_table(guests: int, starts_at: datetime, ends_at: datetime, hall_id: int = None):
    query = """
        SELECT t.*
        FROM restaurant_tables t
        WHERE t.min_guests <= %(guests)s
          AND t.max_guests >= %(guests)s
          AND t.is_active = TRUE
          AND (%(hall_id)s IS NULL OR t.hall_id = %(hall_id)s)
          AND t.id NOT IN (
            SELECT table_id FROM table_bookings
            WHERE status NOT IN ('cancelled', 'no_show')
              AND tsrange(starts_at, ends_at, '[)') && tsrange(%(starts)s, %(ends)s, '[)')
          )
        ORDER BY t.max_guests ASC   -- выбрать наименьший подходящий стол
        LIMIT 1
    """
    return db.fetchone(query, {
        'guests': guests, 'hall_id': hall_id,
        'starts': starts_at, 'ends': ends_at,
    })

Объединение столов

Если нет стола на 8 человек, но есть два смежных стола по 4 — можно предложить объединение. Это требует таблицы смежности:

CREATE TABLE table_adjacency (
    table_a INTEGER REFERENCES restaurant_tables(id),
    table_b INTEGER REFERENCES restaurant_tables(id),
    PRIMARY KEY (table_a, table_b)
);

Подтверждение и напоминания

Время Действие
Сразу SMS/email клиенту с деталями брони
За 24 часа SMS-напоминание
За 2 часа SMS «Ждём вас сегодня в 19:00»
+30 мин после старта Если не пришли — смена статуса на no_show, стол освобождается
+1 день Email с просьбой об отзыве

Депозит при бронировании (опционально) — интеграция с платёжным шлюзом. Депозит списывается, если гость не пришёл и не отменил за N часов.

Сроки реализации

Базовая система с одним залом, сменами и SMS/email уведомлениями — 6–8 рабочих дней. Несколько залов, объединение столов, депозит, управление через CMS, история брони клиента — 10–13 рабочих дней.