Налаштування вибору часу самовивезення 1С-Бітрікс

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

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

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

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

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

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

Зберігання часових слотів

Слоти зберігаються в користувацькому сховищі: або в b_user_field_* як налаштування служби доставки, або в окремій таблиці. Для гнучкості — окрема таблиця:

CREATE TABLE b_pickup_slot (
    ID INT AUTO_INCREMENT PRIMARY KEY,
    STORE_ID INT NOT NULL,
    SLOT_DATE DATE NOT NULL,
    SLOT_TIME_FROM TIME NOT NULL,
    SLOT_TIME_TO TIME NOT NULL,
    CAPACITY INT NOT NULL DEFAULT 10,      -- максимум замовлень у слоті
    BOOKED INT NOT NULL DEFAULT 0,         -- вже заброньовано
    ACTIVE CHAR(1) DEFAULT 'Y',
    INDEX idx_store_date (STORE_ID, SLOT_DATE),
    INDEX idx_active (ACTIVE)
);

Заповнення слотів на тиждень вперед — через агент 1С-Бітрікс, який генерує слоти за розкладом роботи кожної точки.

Отримання доступних слотів через AJAX

// /ajax/pickup-slots.php
\Bitrix\Main\Loader::includeModule('main');

$storeId = (int)($_GET['store_id'] ?? 0);
$date    = $_GET['date'] ?? date('Y-m-d');

if (!$storeId) {
    echo json_encode(['error' => 'store_id required']);
    exit;
}

$connection = \Bitrix\Main\Application::getConnection();
$slots = $connection->query("
    SELECT
        ID,
        DATE_FORMAT(SLOT_TIME_FROM, '%H:%i') as TIME_FROM,
        DATE_FORMAT(SLOT_TIME_TO, '%H:%i') as TIME_TO,
        CAPACITY - BOOKED as AVAILABLE
    FROM b_pickup_slot
    WHERE STORE_ID = ? AND SLOT_DATE = ? AND ACTIVE = 'Y'
      AND BOOKED < CAPACITY
    ORDER BY SLOT_TIME_FROM
", [$storeId, $date])->fetchAll();

header('Content-Type: application/json');
echo json_encode(['slots' => $slots]);

Властивості замовлення для зберігання слоту

Магазин → Налаштування → Властивості замовлення → Додати:

  • PICKUP_SLOT_ID — тип «Число», ID вибраного слоту
  • PICKUP_DATE — тип «Рядок», дата у форматі ДД.ММ.РРРР
  • PICKUP_TIME — тип «Рядок», інтервал «10:00–11:00»

Компонент вибору слоту у формі замовлення

// У шаблоні компонента оформлення замовлення
document.addEventListener('DOMContentLoaded', function() {
    const storeSelect = document.getElementById('pickup-store');
    const dateInput   = document.getElementById('pickup-date');
    const slotList    = document.getElementById('slot-list');

    function loadSlots() {
        const storeId = storeSelect.value;
        const date    = dateInput.value;
        if (!storeId || !date) return;

        slotList.innerHTML = '<li>Завантаження...</li>';

        fetch('/ajax/pickup-slots/?store_id=' + storeId + '&date=' + date)
            .then(r => r.json())
            .then(data => {
                slotList.innerHTML = '';
                if (!data.slots || !data.slots.length) {
                    slotList.innerHTML = '<li>Немає доступних слотів</li>';
                    return;
                }
                data.slots.forEach(slot => {
                    const li = document.createElement('li');
                    li.className = 'slot-option';
                    li.dataset.slotId = slot.ID;
                    li.innerHTML =
                        slot.TIME_FROM + '–' + slot.TIME_TO +
                        ' <span class="available">(' + slot.AVAILABLE + ' місць)</span>';
                    li.addEventListener('click', () => selectSlot(slot));
                    slotList.appendChild(li);
                });
            });
    }

    function selectSlot(slot) {
        document.querySelectorAll('.slot-option').forEach(el => el.classList.remove('active'));
        document.querySelector('[data-slot-id="' + slot.ID + '"]').classList.add('active');

        // Заповнюємо приховані поля властивостей замовлення
        document.querySelector('[name="PICKUP_SLOT_ID"]').value = slot.ID;
        document.querySelector('[name="PICKUP_TIME"]').value =
            slot.TIME_FROM + '–' + slot.TIME_TO;
    }

    storeSelect.addEventListener('change', loadSlots);
    dateInput.addEventListener('change', loadSlots);
});

Бронювання слоту при оформленні замовлення

\Bitrix\Main\EventManager::getInstance()->addEventHandler(
    'sale', 'OnSaleOrderSaved',
    function (\Bitrix\Main\Event $event) {
        $order = $event->getParameter('ENTITY');
        if (!$order->isNew()) {
            return;
        }

        $slotIdProp = $order->getPropertyCollection()
            ->getItemByOrderPropertyCode('PICKUP_SLOT_ID');
        $slotId = $slotIdProp ? (int)$slotIdProp->getValue() : 0;

        if (!$slotId) {
            return;
        }

        // Атомарне збільшення BOOKED з перевіркою CAPACITY
        $connection = \Bitrix\Main\Application::getConnection();
        $affected = $connection->queryExecute("
            UPDATE b_pickup_slot
            SET BOOKED = BOOKED + 1
            WHERE ID = ? AND BOOKED < CAPACITY
        ", [$slotId]);

        if ($connection->getAffectedRowsCount() === 0) {
            // Слот переповнений — сповіщаємо менеджера
            // У production потрібно повернути помилку до збереження замовлення
        }
    }
);

При скасуванні замовлення — зменшуємо BOOKED:

\Bitrix\Main\EventManager::getInstance()->addEventHandler(
    'sale', 'OnSaleOrderCanceled',
    function (\Bitrix\Main\Event $event) {
        $order = $event->getParameter('ENTITY');
        $slotIdProp = $order->getPropertyCollection()
            ->getItemByOrderPropertyCode('PICKUP_SLOT_ID');
        $slotId = $slotIdProp ? (int)$slotIdProp->getValue() : 0;

        if ($slotId) {
            $connection = \Bitrix\Main\Application::getConnection();
            $connection->queryExecute(
                "UPDATE b_pickup_slot SET BOOKED = GREATEST(0, BOOKED - 1) WHERE ID = ?",
                [$slotId]
            );
        }
    }
);

Терміни налаштування

Таблиця слотів, агент генерації розкладу, AJAX-ендпоінт, JS-компонент вибору, збереження у властивості замовлення з атомарним бронюванням — 2–3 робочі дні.