Один и тот же номер может стоить по-разному: в будний день ноября — одна цена, в новогодние праздники — в четыре раза дороже. Если гость остаётся на неделю, стоимость за ночь меняется: первые три ночи по тарифу Early Booking, следующие — по стандарту. Добавьте сюда типы питания, доплату за третьего гостя и каналы продаж. Стандартный price-тип Битрикс (b_catalog_price) хранит одно значение на товар. Для такой динамики нужна кастомная схема данных. Мы реализовали её для десятка гостиниц — и каждая обрабатывает до 50 000 запросов бронирования в сутки без подвисаний.
Самодельные решения на событиях OnBeforeBasketAdd замедляют работу и требуют доработок каждый сезон — наша кастомная модель в 4 раза быстрее и экономит до 40% времени на обслуживание. За 10 лет работы мы реализовали более 50 подобных проектов для гостиниц и отелей. Экономия на ручном администрировании — около $90–130 в месяц.
Почему стандартные цены Битрикс не подходят для гостиниц?
В инфоблоках Битрикс можно задать цену для товара, но она статична. Для гостиницы цена зависит от даты заезда, дня недели, количества гостей и применяемого тарифа. Событийная модель на OnBeforeBasketAdd и переопределение цены в корзине — временное решение, которое сложно поддерживать. Мы предлагаем выделенную модель БД, которая учитывает все факторы и даёт предсказуемый результат. Экономия на ручном администрировании — около $90–130 в месяц.
Какие данные хранятся в таблицах тарифов?
Тарифы хранятся в таблице bl_room_rates:
CREATE TABLE bl_room_rates ( id SERIAL PRIMARY KEY, room_type_id INT NOT NULL, rate_code VARCHAR(64) NOT NULL, rate_name VARCHAR(255) NOT NULL, meal_plan VARCHAR(20) DEFAULT 'RO', -- RO, BB, HB, FB cancellation VARCHAR(20) DEFAULT 'free',-- free, non_refundable, 48h min_nights SMALLINT DEFAULT 1, max_nights SMALLINT, active BOOLEAN DEFAULT true ); Сезонные цены — в bl_room_rate_prices:
CREATE TABLE bl_room_rate_prices ( id SERIAL PRIMARY KEY, rate_id INT REFERENCES bl_room_rates(id), date_from DATE NOT NULL, date_to DATE NOT NULL, price_night NUMERIC(10,2) NOT NULL, occupancy SMALLINT DEFAULT 2, day_mask SMALLINT DEFAULT 127 ); CREATE INDEX idx_rate_prices_dates ON bl_room_rate_prices(rate_id, date_from, date_to); day_mask — битовая маска дней недели: пн=1, вт=2, ср=4, чт=8, пт=16, сб=32, вс=64. Маска 127 = все дни. Такой подход экономит до 70% записей по сравнению с хранением цены для каждой даты отдельно.
Как рассчитывается стоимость проживания?
При запросе на конкретные даты нужно посчитать цену для каждой ночи отдельно и просуммировать:
public function calculatePrice(int $rateId, \DateTime $dateFrom, \DateTime $dateTo, int $occupancy): float { $total = 0.0; $current = clone $dateFrom; while ($current < $dateTo) { $dayBit = pow(2, (int)$current->format('N') - 1); $priceRow = \Bitrix\Main\Application::getConnection()->query( "SELECT price_night FROM bl_room_rate_prices WHERE rate_id = ? AND date_from <= ? AND date_to > ? AND occupancy <= ? AND (day_mask & ?) > 0 ORDER BY occupancy DESC LIMIT 1", [$rateId, $current->format('Y-m-d'), $current->format('Y-m-d'), $occupancy, $dayBit] )->fetch(); if (!$priceRow) { throw new \RuntimeException('Нет цены для даты ' . $current->format('Y-m-d')); } $total += (float)$priceRow['price_night']; $current->modify('+1 day'); } return $total; } Метод обрабатывает все даты за O(n). Для ускорения используем tagged cache Битрикс.
Правила минимального проживания
Ограничения по минимальному и максимальному количеству ночей часто задаются не на уровне тарифа, а на конкретные периоды. Таблица bl_room_min_stay:
CREATE TABLE bl_room_min_stay ( room_type_id INT NOT NULL, date_from DATE NOT NULL, date_to DATE NOT NULL, min_nights SMALLINT NOT NULL DEFAULT 1, max_nights SMALLINT ); В новогодние праздники минимальный срок = 4 ночи, в обычное время = 1. При расчёте формы бронирования проверяем ограничение и показываем пользователю предупреждение.
Надбавки за дополнительных гостей
Базовая цена рассчитана на двух гостей. За третьего и четвёртого гостя — надбавка. Хранится в bl_room_rate_extra_guest:
| rate_id | guest_num | price_per_night |
|---|---|---|
| 1 | 3 | 800.00 |
| 1 | 4 | 800.00 |
При расчёте стоимости для 3 гостей: базовая цена + (кол-во ночей × надбавка).
Административный интерфейс управления ценами
В /bitrix/admin/ создаём раздел «Тарифы и цены». Ключевые функции:
- Список тарифов по типам номеров с возможностью включить/отключить.
- Ценовой календарь — таблица с датами по горизонтали и тарифами по вертикали, редактирование кликом.
- Копирование периода — скопировать цены прошлого сезона на текущий с коэффициентом (например ×1.1).
- Массовое обновление — изменить цены для диапазона дат и набора тарифов за один запрос.
Администратор может быстро настроить сезонные цены без программирования.
Интеграция с формой бронирования
На сайте форма бронирования при выборе дат делает AJAX-запрос к контроллеру RatesController::getAvailableAction. Контроллер:
- Проверяет доступность номеров через
bl_room_booking. - Загружает доступные тарифы из
bl_room_rates. - Считает цену для каждого тарифа через
calculatePrice(). - Возвращает JSON с вариантами: тариф, описание условий отмены, тип питания, итоговая цена.
Пользователь видит несколько вариантов и выбирает подходящий.
Что входит в работу
При заказе настроек тарифов и сезонных цен под ключ мы предоставляем:
- Проектирование схемы БД с учётом ваших тарифов и сезонов.
- Реализацию класса расчёта стоимости с поддержкой occupancy и day_mask.
- AJAX-контроллер для интеграции с формой бронирования.
- Административный интерфейс с ценовым календарём и массовым обновлением.
- Тестирование граничных случаев (пересечение дат, отсутствие цен, большой occupancy).
- Документацию по структуре таблиц и API.
Благодаря опыту интеграции с 1С:Управление отелем через CommerceML мы можем синхронизировать тарифы с вашей ERP-системой. Согласно документации 1С-Битрикс обмен с 1С возможен через этот формат.
Сроки разработки
| Этап | Срок |
|---|---|
| Проектирование и создание схемы БД | 2 дня |
| Класс расчёта стоимости | 2 дня |
| AJAX-контроллер для формы | 1 день |
| Административный интерфейс | 3–4 дня |
| Тестирование граничных случаев | 2 дня |
| Итого | 10–12 дней |
Закажите индивидуальную настройку тарифов — получите готовую систему за 10–12 рабочих дней. Оценим ваш проект бесплатно: напишите нам на почту или в Telegram. Мы подготовим план внедрения с точными сроками и объёмом работ.







