Один і той самий номер може коштувати по-різному: в будній день листопада — одна ціна, в новорічні свята — в чотири рази дорожче. Якщо гість залишається на тиждень, вартість за ніч змінюється: перші три ночі за тарифом Early Booking, наступні — за стандартом. Додайте сюди типи харчування, доплату за третього гостя та канали продажів. Стандартний price-тип Бітрікс (b_catalog_price) зберігає одне значення на товар. Для такої динаміки потрібна кастомна модель цін Бітрікс. Ми реалізували її для десятка готелів — і кожен обробляє до 50 000 запитів бронювання на добу без зависань.
Ми — команда з 10-річним досвідом розробки на 1С-Бітрікс, реалізували понад 50 готельних проєктів. Сертифіковані партнери рівня Gold. На всі роботи надаємо гарантію 12 місяців.
Саморобні рішення на подіях OnBeforeBasketAdd уповільнюють роботу та потребують доопрацювань кожного сезону — наша кастомна модель в 4 рази швидша за них, що економить до 40% часу на обслуговування. Заощаджуємо клієнтам від 20 000 до 50 000 грн на місяць на ручному адмініструванні. Вартість робіт залежить від складності, але починається від 15 000 грн.
Чому стандартні ціни Бітрікс не підходять для готелів?
В інфоблоках Бітрікс можна задати ціну для товару, але вона статична. Для готелю ціна залежить від дати заїзду, дня тижня, кількості гостей і застосованого тарифу. Подієва модель на OnBeforeBasketAdd і перевизначення ціни в кошику — тимчасове рішення, яке складно підтримувати. Ми пропонуємо виділену модель БД, яка враховує всі фактори та дає передбачуваний результат. Економія на ручному адмініструванні — десятки тисяч гривень на місяць.
Які дані зберігаються в таблицях тарифів?
Тарифи зберігаються в таблиці 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% записів порівняно зі зберіганням ціни для кожної дати окремо. Використовується кешування першого рівня (tagged cache) та композитний індекс для прискорення частих запитів.
Алгоритм розрахунку вартості проживання
При запиті на конкретні дати потрібно порахувати ціну для кожної ночі окремо та підсумувати:
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 Бітрікс та composite index на полях (rate_id, date_from, date_to).
Правила мінімального проживання
Обмеження за мінімальною та максимальною кількістю ночей часто задаються не на рівні тарифу, а на конкретні періоди. Таблиця 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. Ми підготуємо план впровадження з точними термінами та обсягом робіт.







