Настройка учета маркированных товаров на 1С-Битрикс

Наша компания занимается разработкой, поддержкой и обслуживанием решений на Битрикс и Битрикс24 любой сложности. От простых одностраничных сайтов до сложных интернет магазинов, CRM систем с интеграцией 1С и телефонии. Опыт разработчиков подтвержден сертификатами от вендора.
Предлагаемые услуги
Показано 1 из 1 услугВсе 1626 услуг
Настройка учета маркированных товаров на 1С-Битрикс
Простая
~1 рабочий день
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • 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С-Битрикс

Учёт маркированных товаров затрагивает весь цикл: приёмка от поставщика → хранение на складе → продажа → возврат. Каждый этап должен отражаться в системе маркировки «Честный Знак». Битрикс сам по себе не является учётной системой для маркировки — но для интернет-магазинов без 1С можно выстроить базовый учёт прямо на Битриксе.

Складской учёт маркированных единиц

Стандартный учёт остатков в Битриксе (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(). При продаже — декрементируете. Это сохраняет совместимость с компонентами каталога Битрикса, которые читают остатки из стандартной таблицы.

Резервирование при оформлении заказа

При добавлении в корзину или при оформлении заказа маркированный товар нужно резервировать — переводить код в статус 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;

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