Настройка инвентаризации через 1С-Битрикс
Инвентаризация ломается на этапе сверки: система показывает 50 единиц, физически 47. Кто-то корректирует остаток вручную через b_catalog_product, минуя документооборот. Через неделю расхождения накапливаются снова, история исчезает.
Документ инвентаризации
Инвентаризация в Битриксе — документ типа I в b_catalog_docs. Отличие от прихода/расхода: в строках документа указывается не дельта, а фактическое количество. Система сама вычисляет разницу с учётными остатками и при проведении применяет корректировку.
Поля b_catalog_docs для инвентаризации: DOC_TYPE = 'I', STORE_FROM и STORE_TO одновременно указывают на один склад (инвентаризация привязана к конкретному складу), STATUS.
Строки в b_catalog_docs_element: AMOUNT — фактически пересчитанное количество, AMOUNT_RESERVED — не используется при инвентаризации. При проведении система читает текущий AMOUNT из b_catalog_store_product для этого склада, вычисляет разницу и применяет её.
Создание документа инвентаризации:
$result = \Bitrix\Catalog\StoreDocumentTable::add([
'DOC_TYPE' => \Bitrix\Catalog\StoreDocumentTable::TYPE_STORE_ADJUSTMENT,
'STATUS' => 'N',
'STORE_TO' => 1,
'TITLE' => 'Инвентаризация ' . date('d.m.Y'),
'DATE_DOCUMENT' => new \Bitrix\Main\Type\DateTime(),
]);
TYPE_STORE_ADJUSTMENT — константа для типа I.
Сбор фактических остатков
Проблема инвентаризации в Битриксе — нет встроенного механизма для поэтапного обхода склада. Стандартный интерфейс требует вносить все позиции разом. Для больших складов это неудобно.
Решение — создавать документ в статусе N и дополнять его строки по мере пересчёта. Пока документ в черновике, он не влияет на остатки. Строки добавляются через \Bitrix\Catalog\StoreDocumentElementTable::add(). Уже добавленные строки обновляются через update() по ID.
Для получения списка всех товаров на складе с текущими учётными остатками:
$storeItems = \Bitrix\Catalog\StoreProductTable::getList([
'filter' => ['STORE_ID' => 1, '>AMOUNT' => 0],
'select' => ['PRODUCT_ID', 'AMOUNT', 'QUANTITY_RESERVED'],
'order' => ['PRODUCT_ID' => 'ASC'],
]);
Этот список служит основой для печатной формы под пересчёт. После физического пересчёта фактические количества вносятся в строки документа.
Проведение и расчёт расхождений
При вызове \Bitrix\Catalog\Document\DocManager::conductDocument($docId) для документа типа I система для каждой строки:
- Читает текущий учётный остаток из
b_catalog_store_product. - Сравнивает с фактическим (
AMOUNTиз строки документа). - Если фактическое меньше — создаёт расход (уменьшает
AMOUNT). - Если больше — создаёт приход (увеличивает
AMOUNT). - Обновляет суммарный
QUANTITYвb_catalog_product.
Товары, которых нет в строках документа, при инвентаризации не затрагиваются. Это позволяет проводить частичную инвентаризацию — только определённую категорию или зону склада.
Нулевые остатки после инвентаризации
Если при инвентаризации физически обнаружено 0 единиц, строку в документ всё равно нужно добавить с AMOUNT = 0. Без этого товар останется с прежним учётным остатком. Многие забывают об этом — особенно при импорте фактических остатков из Excel.
Автоматическое добавление нулевых строк для всех товаров склада:
// Получить все товары склада
$existing = \Bitrix\Catalog\StoreProductTable::getList([
'filter' => ['STORE_ID' => $storeId, '>AMOUNT' => 0],
'select' => ['PRODUCT_ID'],
])->fetchAll();
// Добавить нулевые строки для отсутствующих в документе
foreach ($existing as $item) {
if (!in_array($item['PRODUCT_ID'], $scannedProductIds)) {
\Bitrix\Catalog\StoreDocumentElementTable::add([
'DOC_ID' => $docId,
'ELEMENT_ID' => $item['PRODUCT_ID'],
'STORE_TO' => $storeId,
'AMOUNT' => 0,
]);
}
}
История корректировок
После проведения инвентаризации документ в b_catalog_docs остаётся с STATUS = 'Y' и служит историческим записом. Для аудита расхождений удобно запрашивать документы за период с разницей учётного и фактического количества — это потребует JOIN с b_catalog_store_product на момент проведения, который в стандартном Битрикс не сохраняется. При необходимости полного аудита нужно добавить кастомную таблицу снапшотов остатков до проведения.







