Перейти к содержимому

Штрихкоды товаров - хранение, поиск, приёмка и предложения

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

Что нужно знать заранее

Штрихкод хранится в отдельной таблице каталога, а не в свойстве инфоблока. Это важно: код в своём свойстве выглядит так же, но не участвует ни в приёмке, ни в складских документах.

Код обязан быть уникальным по всей базе и не длиннее ста символов. Повторный код у другого товара не запишется, и сканер на складе иначе показывал бы два разных товара по одному коду.

У товара с торговыми предложениями код принадлежит предложению, а не карточке. Красная футболка сорок шестого размера и синяя сорок восьмого - это разные товары с разными кодами на упаковке.

Шаги

  1. Включить складской учёт в настройках, если планируется приёмка и списание по сканеру.
  2. Определить заранее, куда пишется код: товару без вариантов или конкретному предложению.
  3. Проверить код на уникальность перед записью, а не после отказа платформы.
  4. Записать штрихкоды из файла поставщика пакетом с журналом отклонённых строк.
  5. Проверить поиск по коду на реальном сканере, а не только ручным вводом.

Решение

Записываем штрихкод товару:

$result = \Bitrix\Catalog\StoreBarcodeTable::add([
'PRODUCT_ID' => $productId, // у товара с вариантами - идентификатор предложения
'BARCODE' => '4601234567890', // код обязателен, уникален, до ста символов
]);
if (!$result->isSuccess()) {
print_r($result->getErrorMessages());
}

Результат добавления проверяют всегда: отказ по дублю кода выглядит как молчание. При загрузке пакетом отклонённые строки собирают в отдельный список и отдают товароведу, а не теряют.

Ищем товар по коду со сканера:

$row = \Bitrix\Catalog\StoreBarcodeTable::getRow([
'select' => ['PRODUCT_ID'],
'filter' => ['=BARCODE' => trim($scanned)], // пробелы со сканера отрезаем сразу
]);
printf("товар=%s\n", $row['PRODUCT_ID'] ?? 'не найден');

Поиск идёт по таблице штрихкодов, а не по элементам инфоблока. Это одна выборка по индексированному полю, поэтому она работает одинаково быстро и на тысяче товаров, и на полумиллионе.

Пишем код предложению, а не карточке:

$offers = \CCatalogSKU::getOffersList($productId, 0, [], ['ID', 'NAME']);
foreach ($offers[$productId] ?? [] as $offerId => $offer) {
printf("%d %s\n", $offerId, $offer['NAME']); // код записываем каждому предложению
}
// штрихкод на родительской карточке товара с вариантами сканеру бесполезен

Товар с вариантами - это набор отдельных товаров для склада. Остатки, партии и штрихкоды живут у предложений, и запись кода на родителя не даёт ничего, кроме ложного ощущения порядка.

Смотрим штрихкоды в строках документа:

$rows = \Bitrix\Catalog\StoreDocumentBarcodeTable::getList([
'select' => ['DOC_ELEMENT_ID', 'BARCODE'],
'filter' => ['=DOC_ID' => $documentId],
])->fetchAll();
// у документов со сканированием коды строк лежат в своей таблице

Загружаем коды из файла пакетом:

foreach ($rows as $line) {
$exists = \Bitrix\Catalog\StoreBarcodeTable::getRow([
'select' => ['ID'], 'filter' => ['=BARCODE' => $line['CODE']],
]);
if ($exists) { $skipped[] = $line; continue; } // дубль в файле поставщика
\Bitrix\Catalog\StoreBarcodeTable::add([
'PRODUCT_ID' => $line['PRODUCT_ID'], 'BARCODE' => $line['CODE'],
]);
}

Проверка на существующий код до записи экономит разбор ошибок. Файлы поставщиков регулярно содержат один код у двух позиций, и такие строки честнее отложить, чем записать наугад.

Типичные проблемы

Сканер не находит товар с вариантами.

Код записан на родительскую карточку, а не на конкретное торговое предложение. Штрихкоды складского учёта принадлежат предложениям, а карточка их не хранит.

Штрихкод есть в карточке, но приёмка его не видит.

Код заведён свойством инфоблока, а не в таблице штрихкодов каталога. Свойство инфоблока в складских операциях не участвует и сканеру недоступно.

Часть кодов из файла не загрузилась.

В файле повторяются коды, а поле уникально по всей базе товаров. Отклонённые строки собирают в отдельный список и разбирают вручную вместе с товароведом.

Код со сканера не совпадает с кодом в базе.

В базу попали пробелы или потерялся ведущий ноль при выгрузке из таблицы. Значения приводят к строке и обрезают лишние пробелы прямо при загрузке файла.

Приёмка по сканеру недоступна вовсе.

Складской учёт в настройках модуля каталога выключен, а без него операций нет. Штрихкоды сами по себе складские операции не включают: учёт включают отдельно.

Частые вопросы

Можно ли хранить штрихкод обычным свойством?

Технически да, но тогда он не участвует в приёмке и списании. Для витрины этого хватает, для склада - нет.

Сколько штрихкодов бывает у одного товара?

Несколько: у товара могут быть коды разных упаковок или производителей. Каждый код - отдельная запись, а уникальность проверяется по всей базе.

Как быть с серийными номерами?

Это отдельный режим учёта, где код принадлежит конкретной единице товара. Обычные штрихкоды при этом продолжают работать как коды позиции.

Откуда брать коды при обмене с учётной системой?

Из выгрузки учётной системы: она передаёт коды вместе с товарами. Ручной ввод оставляют для позиций, которых в выгрузке нет.

Что делать с одинаковыми кодами у поставщика?

Разбирать вручную: обычно это ошибка прайса или две упаковки одной позиции. Записывать дубль нельзя, поле уникально по всей базе.

Смежное

Первоисточник