В процессе интеграции 1С с интернет-магазинами часто возникает задача выгрузки не просто общего количества товара, а конкретных серий номенклатуры. Это особенно актуально для учета товаров по серийным номерам, срокам годности или специфическим характеристикам партий. В типовых конфигурациях на обычных формах, таких как «Управление торговым предприятием для Украины» (УТП 1.2) или «Управление торговлей 10.3», базовый механизм обмена часто не включает эти данные в стандартную выгрузку CommerceML.
В данной статье мы подробно разберем, как модифицировать модуль обмена, чтобы сайт начал «видеть» серии номенклатуры, и как сделать так, чтобы каждая серия воспринималась сайтом как отдельная товарная позиция (SKU) или характеристика.
Прежде чем приступать к написанию кода, проанализируем ситуацию. В конфигурации УТП 1.2 (и аналогичных) существует два разных справочника: СерииНоменклатуры и СерийныеНомера. Это важно понимать, так как логика работы с ними отличается:
ТоварыНаСкладах).Если ваша задача — разделить товары на сайте по уникальным кодам серий, мы будем работать именно со справочником СерииНоменклатуры и регистрами остатков.
Рассмотрим основной механизм выгрузки. Практически во всех типовых решениях за формирование XML-файла отвечает обработка ОбменССайтом. Нам необходимо найти в модуле объекта этой обработки процедуру, отвечающую за заполнение реквизитов товара. Обычно она называется ЗаполнитьСписокЗначенийОсновныхРеквизитовТовара.
Эта процедура принимает два параметра: СписокЗначенийCML (структура, которая позже превратится в XML-узлы) и Товар (структура или выборка с данными о текущей номенклатуре).
Одной из главных ошибок при добавлении серий является простой запрос к справочнику СерииНоменклатуры. Если мы просто выберем все серии по владельцу (номенклатуре), сайт получит список всех серий, когда-либо созданных в базе, даже если их давно нет в наличии. Это приведет к замусориванию каталога на сайте.
Правильным подходом будет запрос к регистру накопления ТоварыНаСкладах (или СвободныеОстатки), чтобы получить только те серии, которые реально числятся на складе. Рассмотрим пример кода, который нужно внедрить в процедуру:
// Внутри процедуры ЗаполнитьСписокЗначенийОсновныхРеквизитовТовара
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ТоварыНаСкладахОстатки.СерияНоменклатуры КАК Серия,
| ТоварыНаСкладахОстатки.СерияНоменклатуры.Код КАК КодСерии,
| ТоварыНаСкладахОстатки.СерияНоменклатуры.Наименование КАК НаименованиеСерии
|ИЗ
| РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, Номенклатура = &Номенклатура) КАК ТоварыНаСкладахОстатки";
Запрос.УстановитьПараметр("Номенклатура", Товар.НоменклатураСсылка);
Запрос.УстановитьПараметр("Период", ТекущаяДата());
РезультатЗапроса = Запрос.Выполнить().Выбрать();
Пока РезультатЗапроса.Следующий() Цикл
// Здесь мы добавляем данные серии в XML
ДобавитьУзелCML(СписокЗначенийCML, "НаименованиеСерии", ФорматНаименованияДляCML(РезультатЗапроса.НаименованиеСерии));
ДобавитьУзелCML(СписокЗначенийCML, "КодСерии", РезультатЗапроса.КодСерии);
КонецЦикла;
Выясним причину, по которой сайт может «схлопывать» разные серии в одну карточку товара. В стандарте CommerceML за уникальность отвечает узел <Ид>. Если выгружать разные серии с одним и тем же Ид номенклатуры, сайт будет просто обновлять одну и ту же позицию.
Чтобы каждая серия стала отдельным предложением (SKU), необходимо модифицировать формирование идентификатора. Обычно используется формат ИД_Номенклатуры#ИД_Характеристики#ИД_Серии. Проанализируем, как изменить формирование ИдТовара:
// Формируем уникальный ключ: ИД товара + ИД серии
ИдСерии = "";
Если ЗначениеЗаполнено(РезультатЗапроса.Серия) Тогда
ИдСерии = "#" + СокрЛП(РезультатЗапроса.Серия.УникальныйИдентификатор());
КонецЕсли;
НовыйИдТовара = СформироватьИдентификаторТовара(Товар.НоменклатураСсылка, Товар.ХарактеристикаСсылка) + ИдСерии;
ДобавитьУзелCML(СписокЗначенийCML, "Ид", НовыйИдТовара);
Большинство систем управления сайтом (например, Bitrix) ожидают увидеть серии или другие варианты товара в блоке <ХарактеристикиТовара>. Даже если в самой 1С у вас не включен учет по характеристикам, для сайта их можно имитировать в момент выгрузки. Это позволит покупателю выбирать конкретную серию (например, конкретный серийный номер) из выпадающего списка.
Рассмотрим, как добавить блок характеристик программно:
ДобавитьНачалоЭлементаCML(СписокЗначенийCML, "ХарактеристикиТовара");
ДобавитьНачалоЭлементаCML(СписокЗначенийCML, "ХарактеристикаТовара");
ДобавитьУзелCML(СписокЗначенийCML, "Наименование", "Серия");
ДобавитьУзелCML(СписокЗначенийCML, "Значение", РезультатЗапроса.НаименованиеСерии);
ДобавитьКонецЭлементаCML(СписокЗначенийCML);
ДобавитьКонецЭлементаCML(СписокЗначенийCML);
Часто в серии важно передать номер ГТД. Рассмотрим типичную ошибку: попытку обратиться к полю через точку СерияНоменклатуры.НомерГТД.Код. В старых конфигурациях НомерГТД — это справочник, и если он не заполнен, обращение к его коду вызовет ошибку выполнения запроса.
Проанализируем безопасный способ получения этих данных в запросе:
| ЕСТЬNULL(ТоварыНаСкладахОстатки.СерияНоменклатуры.НомерГТД.Код, "") КАК НомерГТД
Использование функции ЕСТЬNULL или ПРЕДСТАВЛЕНИЕ гарантирует, что программа не «упадет», если у серии не указан таможенный номер.
Мы рассмотрели процесс модификации выгрузки от анализа структуры до написания кода. Подведем итоги необходимых действий:
ТоварыНаСкладах, чтобы получить актуальные данные.import.xml или offers.xml) на наличие новых тегов.Важный момент: помните, что при обновлении конфигурации ваши изменения в модуле ОбменССайтом могут быть затерты. Рекомендуется выносить такие доработки в расширения (если позволяет версия платформы) или фиксировать изменения в хранилище, помечая их комментариями //+ Изменение_Серии.
Реализовав этот алгоритм, мы добьемся того, что сайт получит полную информацию о каждой единице товара, что позволит вести более точные продажи и корректно отображать остатки в разрезе серийных номеров или партий.