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

Учёт остатков на сайте: встроенные средства и плагины

Схема «учёт внутри WooCommerce» означает, что сайт — главное место хранения остатков: сотрудники работают с товарами в админке, а плагины расширяют встроенные возможности. Это базовый вариант, с которого стоит начинать: если его хватает, внешняя товароучётная система не нужна.

WooCommerce уже умеет основное:

  • включать управление запасами на уровне товара и вариации;
  • уменьшать остаток при продаже и возвращать при отмене или возврате;
  • показывать уведомление о низком запасе и порог «нет в наличии»;
  • разрешать или запрещать заказ отсутствующего товара (backorder);
  • различать состояния «в наличии», «нет в наличии», «под заказ».

Настройки находятся в WooCommerce → Settings → Products → Inventory: единицы измерения, порог уведомления, правила для отсутствующих товаров, удержание остатка для незавершённых заказов.

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

Разрешение заказывать отсутствующий товар — не безобидная настройка. Если поставка не подтверждена, backorder превращает нулевой остаток в обещание, которое магазин не может выполнить, а в связке с внешним учётом ещё и создаёт заказы на товар, которого нет ни на одном складе.

Практическое правило: backorder включают только для SKU с подтверждённым сроком поставки, а не глобально для всего каталога.

Встроенный «low stock threshold» — уведомление для сотрудника, а не защита от продажи. Если обмен с внешней системой появится позже, понадобится буфер доступности: заведомое уменьшение количества, компенсирующее задержку обмена. На этапе «всё на сайте» ту же роль играет резерв незавершённых заказов — настройка Hold stock (minutes) в разделе Inventory.

ATUM добавляет то, чего нет в WooCommerce:

  • единый экран остатков вместо перехода по карточкам;
  • поставщиков и закупочные заказы;
  • журналы изменения запасов — кто и когда изменил число;
  • учёт локаций хранения в расширении Multi-Inventory.

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

Важное ограничение: ATUM сам по себе не является готовым обменом с МойСклад или 1С. Это складской слой внутри WordPress, а не интеграция.

Smart Manager показывает товары и остатки в табличном интерфейсе: правки, фильтры, массовые операции. У продукта есть редакции Lite и Pro, набор операций зависит от редакции — сравнение есть в документации.

Когда нужен: сотрудники тратят много времени на однотипные изменения карточек.

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

Мультискладские расширения хранят отдельные количества для складов или других мест хранения. Примеры — ATUM Multi-Inventory и Multi Inventory Management из каталога WooCommerce.

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

При выборе смотрите на три вещи:

  1. Как определяется склад заказа — правилом, близостью к получателю или вручную менеджером.
  2. Как учитываются вариации — остаток по каждому варианту, а не по родительскому товару.
  3. Как считается доступность для покупателя — сумма по складам, конкретный склад или склад по умолчанию.

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

Стандартный интерфейс WooCommerce для остатка — метаданные _stock, _stock_status и _manage_stock, а менять их нужно через API, а не прямым update_post_meta(): иначе не сработают хуки, кэш и пересчёт статуса наличия.

// Изменение остатка с корректным пересчётом статуса и уведомлений.
$product = wc_get_product($product_id);
if ($product && $product->managing_stock()) {
$new_qty = wc_stock_amount($incoming_qty);
$product->set_stock_quantity($new_qty);
$product->set_stock_status($new_qty > 0 ? 'instock' : 'outofstock');
$product->save();
}

Для операций интеграции есть более точный инструмент — wc_update_product_stock(), который умеет уменьшать и увеличивать остаток и сам обновляет статус:

// minus: списание, plus: приход. Функция возвращает новый остаток или WP_Error.
$result = wc_update_product_stock($product_id, $qty, 'minus');
if (is_wp_error($result)) {
error_log('stock sync: ' . $result->get_error_message());
}

Два правила, которые экономят месяцы отладки:

  • Идемпотентность. Повторная доставка одного и того же события (вебхук, повтор задания) не должна списывать дважды. Храните внешний ID операции в метаданных заказа или отдельной таблице и проверяйте его перед записью.
  • Ошибка ≠ ноль. Если внешний API недоступен, остаток не обнуляется и не записывается «на всякий случай». Неудачный запрос — это неудачный запрос, а не сигнал о пустом складе.
  • Нет товарных документов: приёмка, списание и инвентаризация живут только в виде изменения числа.
  • Нет себестоимости и маржинальности по поставкам.
  • Нет общей картины, если тот же товар продаётся в рознице или на маркетплейсе: сайт не узнает о продаже в другом канале.
  • История изменений ограничена тем, что пишет конкретный плагин; без журнала разбор расхождений превращается в археологию.