При настройке интеграции 1С:Управление торговлей 11.4 с интернет-магазином одной из ключевых задач является автоматическое резервирование поступивших товаров. Стандартно менеджеры делают это интерактивно в форме документа «Заказ клиента», выбирая пункт «Заполнить обеспечение». Однако при загрузке заказов через регламентные задания (в фоновом режиме) формы документа отсутствуют. Попытка перенести интерактивный код напрямую приводит к ошибкам, так как большинство типовых механизмов жестко завязаны на контекст формы, структуры ДанныеФормыСтруктура и клиентские вызовы.
В этой статье мы подробно разберем, как решить эту задачу программно на уровне сервера, обойдя ограничения клиентского контекста. Мы рассмотрим два основных метода: решение через расширение конфигурации с использованием внутренних механизмов обработки обеспечения, а также альтернативный и более безопасный способ через типовые общие модули УТ 11.4.
Казалось бы, почему просто не перебрать строки табличной части Товары и не установить значение реквизита ВариантОбеспечения в значение Резервировать со склада (или аналогичное)?
Проблема кроется в ситуациях, когда на складе нет достаточного количества свободного остатка. Если мы принудительно запишем вариант «Со склада» для товара, которого физически нет на складе, система либо выдаст ошибку проведения (при включенном контроле остатков), либо зарезервирует товар «в минус», что полностью нарушит складской учет. Интерактивный механизм работает умнее: он анализирует свободный остаток и, если товара не хватает, разбивает одну исходную строку на две:
Наша главная задача — заставить систему выполнить этот сложный расчет в фоновом режиме при загрузке заказа с сайта.
Проанализировав исходный код конфигурации 1С:УТ 11.4, мы можем обнаружить, что весь ключевой расчет распределения запасов сосредоточен в обработке ОбеспечениеПотребностей. В ее модуле менеджера содержится функция ВыполнитьОбеспечениеЗаказа(). Она идеально подходит под наши требования, так как принимает на вход серверные объекты документов, массивы индексов строк и перечень вариантов обеспечения, работая полностью без клиентского контекста.
Единственная сложность заключается в том, что разработчики фирмы «1С» сделали эту функцию приватной (неэкспортной). Мы не можем вызвать её напрямую из внешних модулей или модулей обмена. Чтобы обойти это ограничение, выполним следующие шаги:
ОбеспечениеПотребностей в наше расширение.Рассмотрим пример кода, который необходимо добавить в модуль менеджера обработки ОбеспечениеПотребностей в расширении:
Функция ВыполнитьОбеспечениеЗаказаЭкспорт(Заказ, ИндексыСтрок, ПереченьВариантов) Экспорт
// Вызываем оригинальный приватный метод типовой конфигурации
Возврат ВыполнитьОбеспечениеЗаказа(Заказ, ИндексыСтрок, ПереченьВариантов);
КонецФункции
Теперь мы можем использовать этот метод в любом месте, где происходит загрузка заказов с сайта. Например, в модуле обмена при записи нового документа нам достаточно вызвать нашу обертку:
// Предположим, что "ЗаказОбъект" — это загруженный и заполненный объект документа ЗаказКлиента
// Подготовим массив индексов строк табличной части "Товары", которые нужно обработать
ИндексыСтрок = Новый Массив;
Для Индекс = 0 По ЗаказОбъект.Товары.Количество() - 1 Цикл
ИндексыСтрок.Добавить(Индекс);
КонецЦикла;
// Определим варианты обеспечения в приоритетном порядке
ПереченьВариантов = Новый Массив;
ПереченьВариантов.Добавить(ПредопределенноеЗначение("Перечисление.ВариантыОбеспечения.СоСклада"));
ПереченьВариантов.Добавить(ПредопределенноеЗначение("Перечисление.ВариантыОбеспечения.Обособленно"));
// Вызываем наш экспортный метод из расширения
Обработки.ОбеспечениеПотребностей.ВыполнитьОбеспечениеЗаказаЭкспорт(ЗаказОбъект, ИндексыСтрок, ПереченьВариантов);
// Записываем и проводим документ
ЗаказОбъект.Записать(РежимЗаписиДокумента.Проведение);
При таком подходе система самостоятельно проанализирует остатки на складе, указанном в заказе, разобьет строки табличной части и установит корректные варианты обеспечения.
Хотя решение через расширение и функцию-обертку полностью работоспособно, использование приватных методов конфигурации несет в себе определенные риски. При обновлении 1С:УТ на новые релизы (например, переход на 11.5) сигнатура внутренней функции ВыполнитьОбеспечениеЗаказа или логика ее вызова могут измениться, что приведет к аварийному завершению фонового обмена.
Для минимизации рисков мы можем использовать полностью официальный программный интерфейс (API), заложенный разработчиками «1С» в общих модулях. Для работы с обеспечением без использования экранных форм предназначен общий модуль ОбеспечениеСервер.
Схема решения в данном случае выглядит следующим образом:
ОбеспечениеСервер.ТаблицаЗаполнениеОбеспеченияДокумента(). На вход она принимает объект документа, массив вариантов обеспечения и параметры. Функция рассчитывает обеспечение и возвращает готовую таблицу значений с распределенными строками.Документы.ЗаказКлиента.ЗаполнитьВариантОбеспечения().Проанализируем пример кода, реализующий эту безопасную схему:
// Шаг 1. Подготовка параметров для расчета обеспечения
ПараметрыЗаполнения = ОбеспечениеСервер.ПараметрыЗаполненияОбеспеченияДокумента(ЗаказОбъект);
ПараметрыЗаполнения.ЗаполнитьПоОстаткам = Истина;
// Определяем варианты, которые нас интересуют (Со склада, при нехватке — К обеспечению)
ВариантыОбеспечения = Новый Массив;
ВариантыОбеспечения.Добавить(Перечисления.ВариантыОбеспечения.СоСклада);
ВариантыОбеспечения.Добавить(Перечисления.ВариантыОбеспечения.КОбеспечению);
// Шаг 2. Расчет распределения остатков на сервере
ТаблицаРаспределения = ОбеспечениеСервер.ТаблицаЗаполнениеОбеспеченияДокумента(
ЗаказОбъект,
ВариантыОбеспечения,
ПараметрыЗаполнения
);
// Шаг 3. Заполнение документа на основании рассчитанных данных
Документы.ЗаказКлиента.ЗаполнитьВариантОбеспечения(ЗаказОбъект, ТаблицаРаспределения);
// Шаг 4. Фиксация изменений в базе данных
ЗаказОбъект.Записать(РежимЗаписиДокумента.Проведение);
Этот способ является наиболее «чистым», так как не требует создания искусственных методов-оберток в расширениях и гарантированно не сломается при очередном минорном обновлении программы.
Даже если ваш программный код написан абсолютно верно, движения по резервам на складах могут не сформироваться. Давайте выясним основные причины, почему это может происходить, и как их избежать.
В 1С:УТ 11 резервы являются «активными» только тогда, когда документ находится в определенном статусе. Если в настройках вашей базы включено использование статусов заказов, то:
Запасы и потребности и Товары на складах документ обязательно должен быть проведен в статусе «Согласован» или «К выполнению».При загрузке заказов с сайта убедитесь, что вы программно устанавливаете документу корректный статус, разрешающий резервирование.
Автоматическое разделение строк на «Со склада» и «К обеспечению» работает корректно только при включенном механизме контроля остатков. Проверьте следующие настройки в вашей базе данных:
Не рекомендуется внедрять код автоматического резервирования непосредственно внутрь модулей обмена с сайтом (особенно если вы используете стандартный модуль интеграции от «1С-Битрикс» или других CMS). Эти модули часто обновляются, и при очередном обновлении ваши доработки могут быть стерты.
Правильнее всего вынести логику авторезервирования в подписку на событие ПередЗаписью или ПриЗаписи для документа ЗаказКлиента. Чтобы логика резервирования отрабатывала только для заказов, пришедших из интернет-магазина, установите простую фильтрацию:
Используя предложенные методы, мы получаем надежный, полностью автоматизированный механизм работы с заказами покупателей, который исключает человеческий фактор и минимизирует вероятность ошибок при распределении складских остатков.