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

Остатки по складам не обновляются - причины по убыванию частоты

Общее количество товара после обмена меняется, а остатки по складам стоят на прежних числах или пустуют. Разбираем причины по убыванию частоты, начиная с того, приехал ли разрез по складам в файл обмена вообще.

С чего начать

Ищем разрез по складам в файле обмена:

Окно терминала
cd /home/bitrix/www/upload/1c_catalog
grep -c 'ИдСклада' offers*.xml rests*.xml 2>/dev/null # узлы количества по складам
grep -o '<Количество>[^<]*' offers*.xml | head -5 # общее количество позиции
grep -o 'ИдСклада>[^<]*' offers*.xml | sort -u | head # коды складов из выгрузки
ls -lt Reports | head -3 # протоколы последних сеансов
# модуль обмена новых версий кладёт остатки отдельным файлом, а не в предложения

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

Смотрим, включён ли складской учёт:

use Bitrix\Main\Loader;
Loader::includeModule('catalog');
var_dump(\Bitrix\Catalog\Config\State::isUsedInventoryManagement());
// при выключенном учёте товар хранит одно общее количество, а склады пустуют
// включение учёта задним числом не наполняет строки по складам за прошлые обмены

Без складского учёта платформа держит остаток одним полем товара. Строки по парам «товар и склад» в этом режиме не наполняются, и показывать разрез по складам оказывается попросту не из чего.

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

$stores = \Bitrix\Catalog\StoreTable::getList([
'select' => ['ID', 'TITLE', 'XML_ID', 'ACTIVE'],
])->fetchAll();
foreach ($stores as $store) {
printf("%-5s %-22s код=%-38s активен=%s\n",
$store['ID'], $store['TITLE'], $store['XML_ID'] ?: 'ПУСТО', $store['ACTIVE']);
}
// код сравнивается строго, название склада при сопоставлении не участвует
// неактивный склад в обмене не участвует и остатков по нему не получит

Код склада из файла обмена ищут среди этих значений посимвольно, а названия при сопоставлении не участвуют вовсе. Незнакомый код означает, что количество приехало, но записать его платформе оказалось некуда.

Смотрим остатки конкретного товара по складам:

$rows = \Bitrix\Catalog\StoreProductTable::getList([
'select' => ['STORE_ID', 'AMOUNT', 'QUANTITY_RESERVED', 'STORE_TITLE' => 'STORE.TITLE'],
'filter' => ['=PRODUCT_ID' => $productId], // у товара с вариантами - ID предложения
])->fetchAll();
foreach ($rows as $row) {
printf("склад %-4s %-22s остаток %s резерв %s\n",
$row['STORE_ID'], $row['STORE_TITLE'], $row['AMOUNT'], $row['QUANTITY_RESERVED']);
}
// пустой ответ означает, что пара «товар и склад» не заводилась ни разу
// доступное к покупке - это остаток минус резерв, а не одно поле остатка
// строки заводит обмен или складской документ, руками их не создают

Отсутствие строки и строка со старым числом - разные состояния разбора. В первом случае остаток по складу не приезжал ни разу, во втором обмен однажды работал и перестал обновлять эту пару.

Проверяем остатки вариантов товара:

$offers = \CCatalogSKU::getOffersList($productId); // предложения товара
$offerIds = array_keys($offers[$productId] ?? []);
$rows = \Bitrix\Catalog\StoreProductTable::getList([
'select' => ['PRODUCT_ID', 'STORE_ID', 'AMOUNT'],
'filter' => ['@PRODUCT_ID' => $offerIds], // остатки живут у вариантов
])->fetchAll();
printf("вариантов %d, строк остатка %d\n", count($offerIds), count($rows));
// у товара с вариантами остаток родителя не участвует в продаже вовсе
// пустой список предложений означает, что каталог настроен без вариантов

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

Причины

  1. Выгрузка идёт без разреза по складам примерно 30% случаев

    ПризнакОбщее количество после обмена меняется, а строк по складам нет ни у одной позиции.

    ПроверкаСчитаем узлы с кодом склада в файле обмена и смотрим отбор складов в настройке выгрузки.

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

  2. Склад сайта не сопоставлен с чужим по внешнему коду примерно 25% случаев

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

    ПроверкаСверяем внешний код каждого склада сайта с кодом склада из узла файла обмена.

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

  3. Складской учёт на сайте выключен примерно 18% случаев

    ПризнакОстатки в файле разложены по складам, а карточка товара показывает одно общее число.

    ПроверкаСмотрим признак включённого складского учёта и наличие строк по парам «товар и склад».

    Что делатьВключаем складской учёт: только в этом режиме общее количество складывается из остатков по складам.

  4. Выгрузка идёт только по изменениям, и позиция в них не попала примерно 12% случаев

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

    ПроверкаСверяем режим выгрузки и читаем журнал обмена: какие позиции попали в последний сеанс.

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

  5. Ноль по складу учётная система не присылает примерно 9% случаев

    ПризнакТовар кончился на складе, а сайт продолжает показывать прежнее ненулевое количество.

    ПроверкаИщем в файле обмена узел склада у позиции, которая обнулилась в учётной системе.

    Что делатьНастраиваем выгрузку нулевых остатков: пропущенный узел сайт понимает как отсутствие данных, а не как ноль.

  6. Остаток заведён родительской карточке вместо предложения примерно 6% случаев

    ПризнакУ товара с вариантами общее число есть, а по складам пусто у каждого варианта.

    ПроверкаПолучаем список предложений товара и запрашиваем складские остатки по их идентификаторам.

    Что делатьПишем и читаем остаток по идентификатору предложения: своих складских строк у карточки-родителя нет.

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

Почему общий остаток обновился, а по складам нет?

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

В каком файле выгружаются остатки по складам?

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

Не выгружаются нулевые остатки на сайт, что делать?

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

Можно ли поправить остаток по складу руками?

Прямая запись по паре товар и склад работает, но не создаёт ни движения, ни партии. На работающем магазине остатки меняют складскими документами с проведением.

Почему у товара с вариантами склады пустые?

Складской остаток хранится у торгового предложения, а не у родительской карточки. Читать и писать его нужно по идентификатору конкретного варианта.

Смежное

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