Настройка календаря доступности номеров на 1С-Битрикс

Наша компания занимается разработкой, поддержкой и обслуживанием решений на Битрикс и Битрикс24 любой сложности. От простых одностраничных сайтов до сложных интернет магазинов, CRM систем с интеграцией 1С и телефонии. Опыт разработчиков подтвержден сертификатами от вендора.
Предлагаемые услуги
Показано 1 из 1 услугВсе 1626 услуг
Настройка календаря доступности номеров на 1С-Битрикс
Простая
~1 рабочий день
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1181
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    813
  • 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 Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Разработка на базе 1С Предприятие для компании МИРСАНБЕЛ
    747
  • image_crm_dolbimby_434_0.webp
    Разработка сайта на CRM Битрикс24 для компании DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Разработка на базе Битрикс24 для компании ТЕХНОТОРГКОМПЛЕКС
    976

Настройка календаря доступности номеров на 1С-Битрикс

Отель пропускает бронирования не потому что нет спроса, а потому что гость не видит свободных дат в реальном времени. Стандартный Битрикс-каталог не умеет работать с датами доступности — это не его задача. Календарь бронирования для номеров требует отдельной архитектуры: хранилища периодов занятости, логики пересечения дат и визуального компонента.

Хранилище периодов занятости

Центральный элемент системы — таблица бронирований:

CREATE TABLE custom_room_bookings (
    id INT AUTO_INCREMENT PRIMARY KEY,
    room_id INT NOT NULL,               -- ID элемента инфоблока (номер)
    order_id INT,                       -- Связь с заказом Битрикс
    guest_name VARCHAR(255),
    check_in DATE NOT NULL,
    check_out DATE NOT NULL,
    status ENUM('pending','confirmed','cancelled') DEFAULT 'pending',
    created_at DATETIME,
    INDEX idx_room_dates (room_id, check_in, check_out),
    INDEX idx_dates (check_in, check_out)
);

Проверка доступности номера на период строится на запросе пересечения интервалов:

SELECT id FROM custom_room_bookings
WHERE room_id = :room_id
  AND status != 'cancelled'
  AND check_in < :check_out
  AND check_out > :check_in
LIMIT 1;

Если запрос возвращает строку — номер занят на запрошенный период.

ORM-обёртка в D7

namespace Custom\Hotel;

class BookingTable extends \Bitrix\Main\ORM\Data\DataManager {
    public static function getTableName(): string { return 'custom_room_bookings'; }

    public static function isRoomAvailable(int $roomId, string $checkIn, string $checkOut): bool {
        $result = static::getList([
            'filter' => [
                '=ROOM_ID' => $roomId,
                '!=STATUS' => 'cancelled',
                '<CHECK_IN' => $checkOut,
                '>CHECK_OUT' => $checkIn,
            ],
            'limit' => 1,
        ]);
        return !$result->fetch();
    }

    public static function getOccupiedDates(int $roomId, string $month): array {
        // Возвращает массив занятых дат для календаря
        $from = date('Y-m-01', strtotime($month));
        $to = date('Y-m-t', strtotime($month));

        $bookings = static::getList([
            'filter' => [
                '=ROOM_ID' => $roomId,
                '!=STATUS' => 'cancelled',
                '<CHECK_IN' => $to,
                '>CHECK_OUT' => $from,
            ],
        ]);

        $dates = [];
        while ($booking = $bookings->fetch()) {
            $current = strtotime($booking['CHECK_IN']);
            $end = strtotime($booking['CHECK_OUT']);
            while ($current < $end) {
                $dates[] = date('Y-m-d', $current);
                $current = strtotime('+1 day', $current);
            }
        }

        return array_unique($dates);
    }
}

Визуальный компонент календаря

Для отображения используется либо готовая JavaScript-библиотека (Flatpickr, Pikaday, Air Datepicker), либо кастомная разработка. Flatpickr — оптимальный выбор: лёгкий (16 KB), поддерживает диапазоны дат, просто стилизуется.

Конфигурация Flatpickr с занятыми датами:

async function initBookingCalendar(roomId) {
    const response = await fetch(`/api/hotel/availability/?room_id=${roomId}&months=3`);
    const { occupiedDates } = await response.json();

    flatpickr('#date-range-picker', {
        mode: 'range',
        minDate: 'today',
        dateFormat: 'Y-m-d',
        locale: 'ru',
        disable: occupiedDates,
        onChange: function(selectedDates) {
            if (selectedDates.length === 2) {
                const nights = Math.round(
                    (selectedDates[1] - selectedDates[0]) / 86400000
                );
                updatePricePreview(roomId, selectedDates[0], selectedDates[1], nights);
            }
        }
    });
}

API-endpoint для данных о доступности

AJAX-контроллер возвращает занятые даты для запрашиваемого периода:

class HotelAvailabilityController extends \Bitrix\Main\Engine\Controller {

    public function getAction(int $roomId, int $months = 2): array {
        $occupiedDates = [];
        $current = new \DateTime();

        for ($m = 0; $m < $months; $m++) {
            $monthStr = $current->format('Y-m');
            $dates = BookingTable::getOccupiedDates($roomId, $monthStr);
            $occupiedDates = array_merge($occupiedDates, $dates);
            $current->modify('+1 month');
        }

        return ['occupiedDates' => array_unique($occupiedDates)];
    }
}

Кэширование ответа — 5 минут через \Bitrix\Main\Data\Cache, инвалидация при новом бронировании.

Ценообразование по датам

Отели часто применяют сезонные тарифы. Цена номера хранится не в торговом предложении Битрикс (оно не поддерживает периоды), а в отдельной таблице тарифов:

CREATE TABLE custom_room_rates (
    id INT AUTO_INCREMENT PRIMARY KEY,
    room_id INT NOT NULL,
    rate_from DATE NOT NULL,
    rate_to DATE NOT NULL,
    price_per_night DECIMAL(10,2) NOT NULL,
    INDEX idx_room_period (room_id, rate_from, rate_to)
);

При выборе дат JavaScript запрашивает итоговую стоимость через отдельный endpoint, суммируя цены за каждую ночь по активным тарифам.

Интеграция с заказами Битрикс

Завершённое бронирование создаёт запись в custom_room_bookings и одновременно оформляет заказ в модуле sale Битрикс. Это сохраняет единый журнал продаж и позволяет использовать стандартные механизмы оплаты и уведомлений.

Сроки выполнения

Объём работ Срок
Хранилище + API доступности + Flatpickr 2–3 дня
Сезонные тарифы + предпросмотр стоимости +1–2 дня
Интеграция с заказами + уведомления +1–2 дня
Синхронизация с Channel Manager (OTA) отдельная задача

Календарь доступности — фундамент всей системы онлайн-бронирования. Именно здесь клиент принимает решение о покупке.