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

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

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

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

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

  • 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С-Бітрікс

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

Модель даних: розклад і слоти

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

Інфоблок «Послуги» (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 тижнів залежно від набору функцій.