При настройке типового обмена 1С с интернет-магазином часто возникает ситуация: цены и физические остатки выгружаются корректно, однако при проведении документов резервирования (например, «Заказ покупателя» или «Резервирование товаров») изменения доступного остатка на сайте не обновляются. Проанализируем причину такого поведения и разберем по шагам, как доработать конфигурацию для корректной регистрации изменений номенклатуры при движениях по резервам.
Типовой механизм выгрузки изменений на сайт отслеживает события записи определенных объектов через подписки на события. В типовой конфигурации «1С:Управление торговлей 10.3» обмен с сайтом по умолчанию отслеживает изменения справочника Номенклатура, регистра сведений ЦеныНоменклатуры и регистра накопления ТоварыНаСкладах. Регистр накопления ТоварыВРезервеНаСкладах в эту цепочку изначально не включен.
Поэтому простого добавления программного кода в общий модуль регистрации изменений недостаточно — обработчик события попросту не будет вызываться при проведении документов, делающих движения только по резервам. Необходимо выполнить комплексную настройку: скорректировать подписку на события и программный код обработчика.
Разберем процесс доработки типового механизма регистрации изменений.
Откроем дерево метаданных конфигурации в режиме Конфигуратора, перейдем в ветку Общие > Подписки на события. Найдем подписку, отвечающую за регистрацию изменений регистров накопления для обмена с сайтом (например, ПриЗаписиРегистраНакопленияОбменССайтом или аналогичную подписку модуля обмена Битрикс). В свойствах подписки в поле Источник необходимо отметить флажком регистр накопления ТоварыВРезервеНаСкладах.
Перейдем в общий модуль, где расположена процедура регистрации изменений (например, ЗарегистрироватьИзменения). Добавим обработку набора записей регистра накопления ТоварыВРезервеНаСкладах.
Посмотрим на пример реализации кода процедуры регистрации изменений:
Процедура ЗарегистрироватьИзменения(Объект)
Если Не ПараметрыСеанса.НаличиеОбменаССайтом Тогда
Возврат;
КонецЕсли;
ТипОбъекта = ТипЗнч(Объект);
// Номенклатура и свойства
Если ТипОбъекта = Тип("РегистрСведенийНаборЗаписей.ЗначенияСвойствОбъектов") Тогда
МассивУзлов = ПолучитьМассивУзловДляРегистрации(Истина);
Для каждого Запись Из Объект Цикл
ТипДанных = ТипЗнч(Запись.Объект);
Если ТипДанных = Тип("СправочникСсылка.Номенклатура") Тогда
ПланыОбмена.ЗарегистрироватьИзменения(МассивУзлов, Запись.Объект);
ИначеЕсли ТипДанных = Тип("СправочникСсылка.ХарактеристикиНоменклатуры") Тогда
ПланыОбмена.ЗарегистрироватьИзменения(МассивУзлов, Запись.Объект.Владелец);
КонецЕсли;
КонецЦикла;
ИначеЕсли ТипОбъекта = Тип("РегистрНакопленияНаборЗаписей.ТоварыНаСкладах")
ИЛИ ТипОбъекта = Тип("РегистрСведенийНаборЗаписей.ЦеныНоменклатуры") Тогда
МассивУзлов = ПолучитьМассивУзловДляРегистрации(Истина);
Для каждого Запись Из Объект Цикл
ПланыОбмена.ЗарегистрироватьИзменения(МассивУзлов, Запись.Номенклатура);
КонецЦикла;
// Регистрация изменений при изменении резервов товара
ИначеЕсли ТипОбъекта = Тип("РегистрНакопленияНаборЗаписей.ТоварыВРезервеНаСкладах") Тогда
МассивУзлов = ПолучитьМассивУзловДляРегистрации(Истина);
Для каждого Запись Из Объект Цикл
ПланыОбмена.ЗарегистрироватьИзменения(МассивУзлов, Запись.Номенклатура);
КонецЦикла;
ИначеЕсли ТипОбъекта = Тип("РегистрСведенийНаборЗаписей.ШтрихКоды") Тогда
МассивУзлов = ПолучитьМассивУзловДляРегистрации(Истина);
Для каждого Запись Из Объект Цикл
Если ТипЗнч(Запись.Владелец) = Тип("СправочникСсылка.Номенклатура") Тогда
ПланыОбмена.ЗарегистрироватьИзменения(МассивУзлов, Запись.Владелец);
КонецЕсли;
КонецЦикла;
ИначеЕсли ТипОбъекта = Тип("СправочникОбъект.ХранилищеДополнительнойИнформации") Тогда
МассивУзлов = ПолучитьМассивУзловДляРегистрации(Истина);
Если ТипЗнч(Объект.Объект) = Тип("СправочникСсылка.Номенклатура")
И Объект.ВидДанных = Перечисления.ВидыДополнительнойИнформацииОбъектов.Изображение Тогда
ПланыОбмена.ЗарегистрироватьИзменения(МассивУзлов, Объект.Объект);
ПланыОбмена.ЗарегистрироватьИзменения(МассивУзлов, Объект.Ссылка);
КонецЕсли;
ИначеЕсли ТипОбъекта = Тип("СправочникОбъект.ХарактеристикиНоменклатуры")
ИЛИ ТипОбъекта = Тип("СправочникОбъект.ЕдиницыИзмерения") Тогда
Если ТипЗнч(Объект.Владелец) = Тип("СправочникСсылка.Номенклатура") Тогда
МассивУзлов = ПолучитьМассивУзловДляРегистрации(Истина);
ПланыОбмена.ЗарегистрироватьИзменения(МассивУзлов, Объект.Владелец);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Рассмотрим подробнее нюансы, которые следует учитывать при промышленной эксплуатации механизма выгрузки резервов:
ПриЗаписи передается пустой набор записей (Объект.Количество() = 0). В таком случае цикл по набору не выполнится, и снятые с резерва позиции не зарегистрируются на узле плана обмена. Для корректной обработки таких случаев логику регистрации часто переносят в обработчик ПередЗаписью, где предварительно считывают старые записи из базы через НаборЗаписей.Прочитать().ХарактеристикаНоменклатуры из набора записей, чтобы сайт получал актуальный свободный остаток по конкретным характеристикам.