Налаштування обліку маркованих товарів на 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 сам по собі не є обліковою системою для маркування — але для інтернет-магазинів без 1С можна вистроїти базовий облік прямо на Bitrix'і.

Складський облік маркованих одиниць

Стандартний облік залишків у Bitrix'і (b_catalog_store_product) працює з кількістю, а не з конкретними екземплярами. Для маркованих товарів потрібен облік на рівні серійних номерів.

Створюєте таблицю серійних номерів (кодів маркування) й прив'язуєте до складу:

CREATE TABLE b_local_marking_inventory (
    ID INT AUTO_INCREMENT PRIMARY KEY,
    PRODUCT_ID INT NOT NULL,          -- ID товару з b_iblock_element
    STORE_ID INT,                      -- ID складу з b_catalog_store
    CODE VARCHAR(200) NOT NULL,        -- Data Matrix код
    GTIN CHAR(14),
    SERIAL VARCHAR(20),
    STATUS ENUM('received','reserved','sold','returned','defective') DEFAULT 'received',
    ORDER_ID INT,                      -- при статусі sold/reserved
    RECEIVED_AT DATETIME,
    UPDATED_AT DATETIME ON UPDATE CURRENT_TIMESTAMP,
    INDEX idx_product_status (PRODUCT_ID, STATUS),
    INDEX idx_code (CODE)
);

Зв'язок з таблицею b_catalog_store_product: при додаванні запису в b_local_marking_inventory зі статусом received інкрементуєте залишок через CCatalogStoreProduct::Update(). При продажі — декрементуєте. Це зберігає сумісність з компонентами каталогу Bitrix'а, які читають залишки зі стандартної таблиці.

Резервування при оформленні замовлення

При додаванні в кошик або при оформленні замовлення маркований товар потрібно зарезервувати — переводити код у статус reserved з прив'язкою до ORDER_ID. Це запобігає продажі одного екземпляра двом покупцям.

Обробник на подію OnSaleBasketItemAdd:

AddEventHandler("sale", "OnSaleBasketItemAdd", function(&$arFields) {
    $productId = $arFields['PRODUCT_ID'];
    if (isMarkedProduct($productId)) {
        // Знаходимо вільний код для товару
        $code = \Local\MarkingCode\InventoryTable::getList([
            'filter' => ['PRODUCT_ID' => $productId, 'STATUS' => 'received'],
            'limit' => 1,
            'select' => ['ID', 'CODE'],
        ])->fetch();

        if (!$code) {
            // Немає доступних екземплярів — блокуємо додавання
            return false;
        }

        // Резервуємо
        \Local\MarkingCode\InventoryTable::update($code['ID'], ['STATUS' => 'reserved']);
        // Зберігаємо ID коду в властивість позиції кошика
        $arFields['PROPS'][] = ['NAME' => 'MARKING_CODE_ID', 'VALUE' => $code['ID']];
    }
});

При скасуванні замовлення — звільняєте зарезервовані коди назад у статус received. Обробник на OnSaleOrderStatusUpdate при переході в статус скасування.

Списання при успішній продажі

При отриманні оплати (подія OnSaleOrderPaid або OnSalePaymentPaid) переводите всі зарезервовані коди у sold й ставляте в чергу на відправлення сповіщення у ГІС МТ:

AddEventHandler("sale", "OnSaleOrderPaid", function($id, $arOrder) {
    $markingCodes = \Local\MarkingCode\InventoryTable::getList([
        'filter' => ['ORDER_ID' => $id, 'STATUS' => 'reserved'],
    ]);

    while ($code = $markingCodes->fetch()) {
        \Local\MarkingCode\InventoryTable::update($code['ID'], ['STATUS' => 'sold']);
        \Local\MarkingCode\NotificationQueue::add([
            'CODE' => $code['CODE'],
            'ORDER_ID' => $id,
            'OPERATION' => 'SALE',
        ]);
    }
});

Звітність по маркованим товарам

Для аналітики — адміністративна сторінка у /local/admin/marking_report.php з вибіркою по статусам, датам, товарам. Агрегація через прямі SQL-запити до b_local_marking_inventory:

SELECT PRODUCT_ID,
    COUNT(*) as total,
    SUM(STATUS = 'received') as in_stock,
    SUM(STATUS = 'sold') as sold
FROM b_local_marking_inventory
GROUP BY PRODUCT_ID;

Щоденна звірка: кількість проданих кодів повинна збігатися з кількістю товарів у виконаних замовленнях. Розбіжність сигналізує про помилку в обробниках подій.