Налаштування тригера надходження товару на склад 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С-Bitrix

Товар закінчується, користувач натискає «Повідомити про поступлення» і... нічого. Лист ніколи не приходить, тому що ніхто не налаштував зв'язок між подією поповнення складу та списком очікування. Це частий кейс: форма підписки є, склад поповнюється, але автоматика не запущена.

Де зберігаються залишки та як вони оновлюються

В Bitrix залишки товарів живуть у двох місцях залежно від конфігурації:

Простий каталог (без складського обліку): поле CATALOG_QUANTITY у b_catalog_product. Оновлюється напрямко через CCatalogProduct::Update() або через обмін з 1С.

Багатоскладський облік (модуль catalog + склади): таблиця b_catalog_store_product з полями PRODUCT_ID, STORE_ID, AMOUNT. Загальний залишок агрегується. При обміні 1С через модуль sale.crm.lead або через стандартний обмін дані пишуться в b_catalog_store_product.

Подія зміни залишку — OnProductUpdate у модулі catalog. Вона спрацьовує при будь-якій зміні записи в b_catalog_product, включаючи кількість:

AddEventHandler('catalog', 'OnProductUpdate', function($id, $fields) {
    if (isset($fields['QUANTITY']) && $fields['QUANTITY'] > 0) {
        // Товар поступив на склад — була нульова позиція
        checkAndNotifyWaitlist($id);
    }
});

Проблема: OnProductUpdate спрацьовує при будь-якій зміні продукту, не тільки при поповненні складу. Щоб відфільтрувати саме подію «з'явився з нуля», потрібно порівняти попереднє значення. До PHP-события дані ще в БД, тому читаємо старе значення в OnBeforeProductUpdate:

AddEventHandler('catalog', 'OnBeforeProductUpdate', function($id, &$fields) {
    $old = \Bitrix\Catalog\ProductTable::getByPrimary($id, ['select' => ['QUANTITY']])->fetch();
    $fields['_OLD_QUANTITY'] = (float)($old['QUANTITY'] ?? 0);
});

Зберігання підписок на поступлення

Модуль catalog не має вбудованого механізму «повідомити про поступлення». Потрібна власна таблиця:

CREATE TABLE bl_stock_notify (
    id          SERIAL PRIMARY KEY,
    product_id  INT NOT NULL,
    user_id     INT,
    email       VARCHAR(255) NOT NULL,
    created_at  TIMESTAMP DEFAULT NOW(),
    notified_at TIMESTAMP,
    UNIQUE (product_id, email)
);

Форма на сайті пише в цю таблицю. Унікальний ключ (product_id, email) захищає від дублів при повторних підписках.

Обробник поповнення

function checkAndNotifyWaitlist(int $productId): void
{
    $connection = \Bitrix\Main\Application::getConnection();
    $waitlist = $connection->query(
        "SELECT * FROM bl_stock_notify WHERE product_id = {$productId} AND notified_at IS NULL"
    )->fetchAll();

    if (empty($waitlist)) {
        return;
    }

    $product = \CIBlockElement::GetByID($productId)->GetNextElement();
    $name    = $product->GetField('NAME');
    $url     = $product->GetField('DETAIL_PAGE_URL');

    foreach ($waitlist as $row) {
        \Bitrix\Main\Mail\Event::send([
            'EVENT_NAME' => 'STOCK_ARRIVED',
            'LID'        => SITE_ID,
            'C_FIELDS'   => [
                'EMAIL'        => $row['email'],
                'PRODUCT_NAME' => $name,
                'PRODUCT_URL'  => 'https://' . $_SERVER['SERVER_NAME'] . $url,
            ],
        ]);

        $connection->queryExecute(
            "UPDATE bl_stock_notify SET notified_at = NOW() WHERE id = {$row['id']}"
        );
    }
}

Інтеграція з багатоскладським обліком

При багатоскладському обліку подія OnProductUpdate не спрацьовує при зміні b_catalog_store_product. Для складських операцій потрібно підписатися на события модулю catalog глибшого рівня — або використовувати хук після запису документа складського обліку через \Bitrix\Catalog\Document\DocumentTable.

Альтернативний підхід: агент, який кожні 5 хвилин перевіряє b_catalog_store_product на появу ненульових залишків за товарами з листа очікування. Менш елегантно, але працює стабільніше при нестандартних схемах оновлення залишків (наприклад, при прямому UPDATE через 1С-коннектор).

Що ми налаштовуємо

  • Обробники OnBeforeProductUpdate та OnProductUpdate з перевіркою переходу «0 → N»
  • Таблицю bl_stock_notify та форму підписки на сайті
  • Шаблон листа STOCK_ARRIVED в адміністративному розділі поштових подій
  • Для багатоскладської конфігурації — агент або обробник документів складу
  • Логіку часткового поступлення: якщо прийшло 2 одиниці, а підписалось 10 — повідомити всіх або перших двох?