Разработка системы записи на услуги на 1С-Битрикс

Наша компания занимается разработкой, поддержкой и обслуживанием решений на Битрикс и Битрикс24 любой сложности. От простых одностраничных сайтов до сложных интернет магазинов, CRM систем с интеграцией 1С и телефонии. Опыт разработчиков подтвержден сертификатами от вендора.
Предлагаемые услуги
Показано 1 из 1 услугВсе 1626 услуг
Разработка системы записи на услуги на 1С-Битрикс
Средняя
~1-2 недели
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1177
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    811
  • 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С-Битрикс

Стандартный модуль «Интернет-магазин» Битрикса заточен под товары с немедленной оплатой, а не под услуги с временными слотами. Попытка записать клиента на стрижку, консультацию или занятие, используя только стандартный функционал корзины и заказов — приводит к нагромождению костылей: товар с нулевым остатком = «занято», XML-поле = «время», email-ы вместо реального расписания. Полноценная система записи требует отдельной архитектуры.

Модель данных: расписание и слоты

Ядро системы — инфоблок расписания. Оптимальная структура:

Инфоблок «Услуги» (SERVICES_IBLOCK_ID):

  • Стандартные поля: NAME, PREVIEW_TEXT, DETAIL_TEXT
  • Свойства: DURATION (продолжительность в минутах), PRICE, MAX_CAPACITY (групповые занятия), SPECIALIST_ID (привязка к специалисту)

Инфоблок «Расписание» (SCHEDULE_IBLOCK_ID):

  • SERVICE_ID — привязка к услуге
  • SPECIALIST_ID — исполнитель
  • DATE_FROM, DATE_TO — начало и конец слота (свойства типа «Дата/время»)
  • STATUSfree/booked/blocked
  • BOOKING_ID — ID записи (после бронирования)

Таблица бронирований (кастомная или через highload-блок):

CREATE TABLE bookings (
    ID INT AUTO_INCREMENT PRIMARY KEY,
    SLOT_ID INT NOT NULL,        -- ID элемента расписания
    USER_ID INT,                 -- ID пользователя (NULL для незарегистрированных)
    CLIENT_NAME VARCHAR(255),
    CLIENT_PHONE VARCHAR(20),
    CLIENT_EMAIL VARCHAR(255),
    STATUS ENUM('pending','confirmed','cancelled','completed') DEFAULT 'pending',
    COMMENT TEXT,
    CREATED_AT DATETIME,
    UPDATED_AT DATETIME,
    INDEX (SLOT_ID),
    INDEX (STATUS)
);

Генерация слотов расписания

Слоты генерируются на основе шаблонов рабочего времени. Подход: хранить шаблоны недельного расписания специалиста и автоматически создавать слоты на N недель вперёд.

class SlotGenerator
{
    public function generateForSpecialist(int $specialistId, \DateTime $from, \DateTime $to): void
    {
        $schedule = $this->getWeeklySchedule($specialistId); // [0=>[], 1=>['09:00','13:00',...]]
        $serviceDuration = $this->getServiceDuration($specialistId); // минуты

        $current = clone $from;
        while ($current <= $to) {
            $dayOfWeek = (int)$current->format('N'); // 1=пн, 7=вс
            $daySlots = $schedule[$dayOfWeek] ?? [];

            foreach ($daySlots as $timeRange) {
                [$start, $end] = explode('-', $timeRange); // '09:00-13:00'
                $this->createSlotsBetween($specialistId, $current, $start, $end, $serviceDuration);
            }
            $current->modify('+1 day');
        }
    }
}

Слоты создаются как элементы инфоблока со статусом free. При бронировании — статус меняется на booked, при отмене — обратно на free.

Виджет выбора времени: логика на фронте

Пользователь выбирает услугу → специалиста → дату → время. Каждый шаг — AJAX-запрос к кастомному контроллеру:

// /local/ajax/booking.php
class BookingController extends \CBitrixComponent
{
    public function getAvailableSlots(int $specialistId, string $date): array
    {
        $dateFrom = new \Bitrix\Main\Type\DateTime($date . ' 00:00:00');
        $dateTo = new \Bitrix\Main\Type\DateTime($date . ' 23:59:59');

        $result = \Bitrix\Iblock\ElementTable::getList([
            'filter' => [
                'IBLOCK_ID' => SCHEDULE_IBLOCK_ID,
                '=PROPERTY_SPECIALIST_ID' => $specialistId,
                '>=PROPERTY_DATE_FROM' => $dateFrom,
                '<=PROPERTY_DATE_FROM' => $dateTo,
                '=PROPERTY_STATUS' => 'free',
                '=ACTIVE' => 'Y',
            ],
            'select' => ['ID', 'PROPERTY_DATE_FROM', 'PROPERTY_DATE_TO'],
            'order' => ['PROPERTY_DATE_FROM' => 'ASC'],
        ]);
        // ...
    }
}

На фронте — календарь (например, FullCalendar или кастомный на React) с подсветкой доступных дней и временных слотов.

Обработка гонки условий при бронировании

Если два пользователя одновременно выбрали один слот, нужно гарантировать, что только один получит бронь. Решение через оптимистичную блокировку на уровне БД:

public function bookSlot(int $slotId, array $clientData): BookingResult
{
    // Транзакция + блокировка строки
    $connection = \Bitrix\Main\Application::getConnection();
    $connection->startTransaction();

    try {
        // SELECT FOR UPDATE — блокируем строку
        $slot = $connection->query(
            "SELECT * FROM b_iblock_element_property
             WHERE IBLOCK_ELEMENT_ID = {$slotId} AND IBLOCK_PROPERTY_ID = " . STATUS_PROP_ID . "
             FOR UPDATE"
        )->fetch();

        if ($slot['VALUE'] !== 'free') {
            $connection->rollbackTransaction();
            return BookingResult::slotTaken();
        }

        // Обновляем статус слота
        $this->updateSlotStatus($slotId, 'booked');

        // Создаём бронирование
        $bookingId = $this->createBooking($slotId, $clientData);

        $connection->commitTransaction();
        return BookingResult::success($bookingId);

    } catch (\Exception $e) {
        $connection->rollbackTransaction();
        throw $e;
    }
}

Уведомления и напоминания

После бронирования — немедленное уведомление клиенту и специалисту. За 24 часа и за 2 часа — напоминания. Реализация через агенты Битрикса:

// Создаём агент-напоминание при бронировании
\CAgent::AddAgent(
    '\BookingModule\ReminderAgent::send(' . $bookingId . ');',
    'my_booking_module',
    'N', // не периодический
    0,
    '',
    'Y',
    ConvertTimeStamp($bookingDateTs - 86400, 'FULL') // за 24 часа
);

Канал уведомлений: email (через модуль main), SMS (через внешний шлюз), Telegram-бот. Шаблоны уведомлений — через стандартные почтовые события Битрикса (CEvent::Send).

Интеграция с оплатой

Если запись требует предоплаты — создаём заказ в интернет-магазине Битрикса:

$order = \Bitrix\Sale\Order::create(SITE_ID, $userId);
$order->setPersonTypeId(1);

$basket = $order->getBasket();
$item = \Bitrix\Sale\BasketItem::create($basket, 'catalog', $serviceElementId);
$item->setFields(['QUANTITY' => 1, 'PRICE' => $servicePrice, 'NAME' => $serviceName]);
$basket->addItem($item);

$order->save();
// Перенаправляем на страницу оплаты

Связь бронирования с заказом хранится в таблице через поле ORDER_ID. При оплате заказа — вебхук или обработчик события OnSaleOrderPaid подтверждает бронирование.

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

Для администраторов и специалистов — страница в разделе /bitrix/admin/ с:

  • Просмотром всех броней на дату (calendar view)
  • Возможностью блокировать слоты (отпуск, обед)
  • Ручным подтверждением/отменой с отправкой уведомления клиенту
  • Выгрузкой в CSV за период

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

Этап Содержание Срок
Проектирование Модель данных, сценарии использования 3–5 дней
Инфоблоки и генератор слотов Создание структуры, генерация расписания 1 неделя
AJAX-контроллеры API выбора слота, бронирования 1 неделя
Фронтенд-виджет Календарь, выбор специалиста и времени 1–2 недели
Уведомления Email, SMS, напоминания через агенты 3–5 дней
Административный интерфейс Управление расписанием, просмотр броней 1 неделя
Интеграция с оплатой (опционально) Предоплата через заказы 1 неделя

Суммарно: 6–10 недель в зависимости от набора функций.