Склады и остатки - выгрузка, вывод наличия, фильтр по складу
Включаем складской учёт, принимаем остатки из учётной системы и выводим наличие на витрине магазина.
Решение
Смотрим, включён ли складской учёт и какие склады заведены:
use Bitrix\Main\Loader;
Loader::includeModule('catalog');echo COption::GetOptionString('catalog', 'default_use_store_control'), "\n";// значение Y означает включённый складской учёт по всему каталогу$res = CCatalogStore::GetList([], ['ACTIVE' => 'Y'], false, false, ['ID', 'TITLE', 'XML_ID']);while ($store = $res->Fetch()) { printf("%-6s %-24s код=%s\n", $store['ID'], $store['TITLE'], $store['XML_ID'] ?: '(пусто)');}Пустой внешний код склада - главная причина нулевых остатков после обмена. Учётная система присылает остатки вместе с кодом своего склада, и сопоставить этот код на стороне сайта оказывается попросту не с чем.
Читаем остатки товара по складам:
$res = CCatalogStoreProduct::GetList([], ['PRODUCT_ID' => $productId], false, false, ['STORE_ID', 'AMOUNT']);$total = 0;while ($row = $res->Fetch()) { printf("склад %-6s остаток %s\n", $row['STORE_ID'], $row['AMOUNT']); $total += $row['AMOUNT']; // общее количество складывается из складов}// свободный остаток меньше складского на величину резерва по заказамОстатки лежат отдельной таблицей: строка на пару «товар и склад». Общее количество товара при включённом учёте пересчитывается из этих строк, и править его напрямую бесполезно.
При включённом складском учёте остаток правят документами, а не полем товара. Приход, списание, перемещение и отмена резерва - это отдельные документы, и устройство этого механизма разобрано в статье про продвинутый каталог.
Выводим наличие на витрине:
'USE_STORE' => 'Y', // показывать наличие по складам'SHOW_GENERAL_STORE_INFORMATION' => 'Y','STORES' => [1, 2], // какие склады показывать посетителю'SHOW_EMPTY_STORE' => 'N', // склады с нулём не выводитьКомпонент показывает не число, а текст по настройкам магазина: «в наличии», «мало», «под заказ». Пороги для этих надписей задаются в настройках модуля, а не в шаблоне компонента.
Фильтруем товары по наличию:
$res = CIBlockElement::GetList(['CATALOG_QUANTITY' => 'DESC'], [ 'IBLOCK_ID' => 5, '>CATALOG_QUANTITY' => 0, // только позиции с ненулевым остатком], false, false, ['ID', 'NAME', 'CATALOG_QUANTITY']);Количество приходит из торгового каталога, а не из свойств инфоблока. Поэтому в умном фильтре наличие включают отдельным параметром компонента, а не флагом свойства.
Резерв уменьшает доступное количество, но не трогает складской остаток. Товар, попавший в неоплаченный заказ, продолжает числиться на складе и при этом не продаётся дальше. Отсюда расхождение между цифрой в админке и тем, что видит покупатель на витрине: разницу составляют именно резервы по текущим заказам.
Число складов ограничено редакцией продукта. Лишние склады при обмене просто не создаются, и остатки по ним не приходят вовсе - без единой ошибки в журнале. Когда складов в учётной системе больше, их объединяют в один сводный склад на стороне выгрузки, а не на сайте.
Типичные проблемы
Остатки приходят нулевыми при непустой выгрузке.
Склады сайта и склады учётной системы не сопоставлены по внешнему коду. Названия при сопоставлении не используются вовсе.
Правка количества у товара не сохраняется.
Включён складской учёт, и общее количество пересчитывается из остатков по складам. При включённом учёте остаток меняют только складским документом, а не полем товара.
Часть складов не появилась после обмена.
Их число превышает предел редакции. Лишние склады не создаются молча, ошибки в журнале обмена нет.
На витрине наличие показано текстом, а нужно число.
Компонент выводит надписи по настройкам магазина. Числовое количество включается отдельным параметром.
Товар в наличии, но купить нельзя.
У товара включён запрет продажи при нулевом остатке, а остаток резервируется другими заказами. Доступное количество меньше складского на величину резерва.
Частые вопросы
Нужен ли складской учёт обычному магазину?
Если склад один и остатки приходят общим числом, учёт только усложняет обмен. Он нужен там, где наличие показывается по точкам выдачи или резерв ведётся по складам.
Как объединить остатки нескольких складов?
Суммой на стороне выгрузки: сайт получает один сводный склад. Складывать их на сайте можно кодом, но резерв и продажи всё равно ведутся по конкретным складам.
Почему товар в наличии, а сортировка ставит его в конец?
Сортировка идёт по полю, которое указано в параметрах компонента. Количество - поле торгового каталога, и его нужно назвать явно.
Как скрыть остатки от посетителей?
Отключением показа наличия в параметрах компонента. Данные при этом остаются в базе и продолжают участвовать в проверке доступности товара.
Смежное
-
Склады и остатки - оглавление подтемы
-
Остаток товара не тот: разбор причин - когда числа расходятся с реальностью
-
Штрихкоды товаров: хранение, поиск, приёмка и предложения - поиск товара по коду со сканера
-
Складские документы: приход, списание, перемещение, резерв - как менять остатки правильно
-
Не выгружаются цены и остатки из 1С - разбор причин при обмене
-
Прайс поставщика по расписанию: сопоставление, наценка, защита - остатки из файла поставщика
-
Витрина каталога: список раздела, сортировка, фильтр - вывод списка товаров
-
Региональность магазина: выбор города, цены и склады - склады, привязанные к городам
-
Каталог и продажи - устройство магазина целиком
-
Остатки из 1С: сопоставление складов и приём количества - откуда берутся остатки на сайте
-
Подписка на поступление товара: уведомление о наличии - что предложить покупателю при нуле
-
Оплаты и отгрузки заказа: объекты, признаки, частичные операции - что снимает резерв со склада
-
Самовывоз и пункты выдачи: склады, список на оформлении, заказ - склады как пункты выдачи заказа
-
Товары под заказ: продажа при нулевом остатке и сроки - продажа при нулевом остатке
-
Резервирование товара: момент резерва, снятие, доступное количество - почему остаток и продажа расходятся
-
Низкие остатки: пороги, отчёт закупщику, поведение витрины - контроль кончающегося товара
-
Остатки по складам не обновляются: разбор причин - разбор пустого разреза по складам