Налаштування модуля онлайн-бронювання номерів на 1С-Бітрікс

Наша компанія займається розробкою, підтримкою та обслуговуванням рішень на Бітрікс та Бітрікс24 будь-якої складності. Від простих односторінкових сайтів до складних інтернет-магазинів, CRM систем з інтеграцією 1С та телефонії. Досвід розробників підтверджено сертифікатами від вендора.
Пропоновані послуги
Показано 1 з 1 послугУсі 1626 послуг
Налаштування модуля онлайн-бронювання номерів на 1С-Бітрікс
Проста
~1 робочий день
Часті питання

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

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Розробка на базі Бітрікс, Бітрікс24, 1С для компанії Development of an Online
    585
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Розробка на базі 1С Підприємство для компанії МИРСАНБЕЛ
    751
  • image_crm_dolbimby_434_0.webp
    Розробка сайту на CRM Бітрікс24 для компанії DOLBIMBY
    657
  • image_crm_technotorgcomplex_453_0.webp
    Розробка на базі Бітрікс24 для компанії ТЕХНОТОРГКОМПЛЕКС
    989

Налаштування модуля онлайн-бронювання номерів на 1С-Бітрікс

У 1С-Бітрікс немає стандартного модуля бронювання номерів. Є модуль sale (замовлення), інфоблоки, агенти. З цього збирається система бронювання, але розрив між «є інструменти» і «бронювання працює» — це кілька тижнів проєктування і розробки. Головна технічна проблема, яку вирішує модуль: атомарна перевірка доступності із захистом від одночасного резервування одного номера двома користувачами.

Структура даних

Типова схема для об'єктів розміщення:

Інфоблок hotel_rooms — каталог номерів:

  • PROPERTY_ROOM_TYPE — тип (стандарт, люкс, апартаменти)
  • PROPERTY_CAPACITY — місткість
  • PROPERTY_AREA — площа
  • PROPERTY_FLOOR — поверх
  • PROPERTY_BED_TYPE — тип ліжок (одне двоспальне, два односпальних)
  • PROPERTY_AMENITIES — список зручностей (множинна властивість)

Таблиця бронювань bl_room_booking:

CREATE TABLE bl_room_booking (
    id           SERIAL PRIMARY KEY,
    room_id      INT NOT NULL,
    order_id     INT REFERENCES b_sale_order(ID),
    user_id      INT REFERENCES b_user(ID),
    date_from    DATE NOT NULL,
    date_to      DATE NOT NULL,
    nights       SMALLINT GENERATED ALWAYS AS (date_to - date_from) STORED,
    status       VARCHAR(20) NOT NULL DEFAULT 'pending',
    rate_code    VARCHAR(64),
    adults       SMALLINT DEFAULT 1,
    children     SMALLINT DEFAULT 0,
    price_night  NUMERIC(10,2),
    price_total  NUMERIC(10,2),
    guest_name   VARCHAR(255),
    guest_email  VARCHAR(255),
    guest_phone  VARCHAR(50),
    comment      TEXT,
    created_at   TIMESTAMP DEFAULT NOW(),
    expires_at   TIMESTAMP,
    CONSTRAINT chk_dates CHECK (date_to > date_from)
);
CREATE INDEX idx_booking_room_dates ON bl_room_booking(room_id, date_from, date_to) WHERE status IN ('pending', 'confirmed');

Атомарна перевірка і створення бронювання

Race condition — головний ворог систем бронювання. Два користувачі одночасно відкрили форму на один номер, обидва перевірили доступність (вільно), обидва натиснули «Забронювати». Без блокування обидва отримують підтвердження.

Рішення — транзакція з явним блокуванням рядка:

$connection = \Bitrix\Main\Application::getConnection();
$connection->startTransaction();

try {
    // Блокуємо запис номера для оновлення
    $connection->query(
        "SELECT id FROM bl_room_booking
         WHERE room_id = ?
           AND status IN ('pending', 'confirmed')
           AND date_from < ?
           AND date_to > ?
         FOR UPDATE",
        [$roomId, $dateTo, $dateFrom]
    );

    $conflicts = $connection->getAffectedRowsCount();
    if ($conflicts > 0) {
        $connection->rollbackTransaction();
        return ['error' => 'Номер недоступний на обрані дати'];
    }

    $bookingId = $connection->query(
        "INSERT INTO bl_room_booking
         (room_id, user_id, date_from, date_to, status, expires_at, price_total)
         VALUES (?, ?, ?, ?, 'pending', NOW() + INTERVAL '20 minutes', ?)
         RETURNING id",
        [$roomId, $userId, $dateFrom, $dateTo, $totalPrice]
    )->fetch()['id'];

    $connection->commitTransaction();
    return ['booking_id' => $bookingId];
} catch (\Exception $e) {
    $connection->rollbackTransaction();
    throw $e;
}

Зв'язок із модулем sale

Після створення бронювання зі статусом pending створюємо замовлення в модулі sale:

$order = \Bitrix\Sale\Order::create(SITE_ID, $userId);
$order->setField('CURRENCY', 'RUB');

$basket = $order->getBasket();
$item = \Bitrix\Sale\BasketItem::create($basket, 'catalog', $roomProductId);
$item->setFields([
    'NAME'      => 'Номер ' . $roomName . ' (' . $nights . ' ночей)',
    'QUANTITY'  => 1,
    'PRICE'     => $totalPrice,
    'CURRENCY'  => 'RUB',
]);
$basket->addItem($item);
$order->save();

// Прив'язуємо order_id до бронювання
BookingTable::update($bookingId, ['ORDER_ID' => $order->getId()]);

При оплаті замовлення (подія OnSalePaymentEntitySaved, IS_PAID = Y) переводимо бронювання в confirmed.

Агент звільнення прострочених бронювань

Бронювання зі статусом pending та вичерпаним expires_at мають звільнятися автоматично:

function ReleaseExpiredRoomBookings(): string
{
    \Bitrix\Main\Application::getConnection()->queryExecute(
        "UPDATE bl_room_booking
         SET status = 'expired'
         WHERE status = 'pending' AND expires_at < NOW()"
    );
    // Скасовуємо пов'язані замовлення в sale
    $expired = \Bitrix\Main\Application::getConnection()->query(
        "SELECT order_id FROM bl_room_booking WHERE status = 'expired' AND order_id IS NOT NULL AND notified = false"
    );
    while ($row = $expired->fetch()) {
        $order = \Bitrix\Sale\Order::load($row['order_id']);
        if ($order) $order->setField('STATUS_ID', 'CANCEL');
    }
    return __FUNCTION__ . '();';
}

Агент реєструється з інтервалом 60 секунд.

Адміністративний інтерфейс

До /bitrix/admin/ додається розділ «Бронювання». Ключові представлення:

  • Календарна сітка — рядки = типи номерів, стовпці = дати. Комірки пофарбовані за статусом бронювання. Реалізується через кастомну сторінку з таблицею з bl_room_booking.
  • Список бронювань — стандартний грід із фільтрами за статусом, датами, гостем.
  • Картка бронювання — деталі, кнопки зміни статусу, прив'язане замовлення.

Терміни

Етап Термін
Інфоблок номерів + схема БД 2 дні
Бекенд: перевірка, створення, агент 4 дні
Форма бронювання на сайті (AJAX, календар) 3 дні
Зв'язок із модулем sale і платіжними системами 2 дні
Адміністративний інтерфейс 3 дні
Тестування 2 дні
Разом 2–3 тижні