diff --git a/VERSION b/VERSION index 631d9de..0ef281a 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.3.0.35 +1.3.0.37 diff --git a/src/CommonModules/МенеджерОбменаЧерезУниверсальныйФормат/Ext/Module.bsl b/src/CommonModules/МенеджерОбменаЧерезУниверсальныйФормат/Ext/Module.bsl index a1622db..0fa3efa 100644 --- a/src/CommonModules/МенеджерОбменаЧерезУниверсальныйФормат/Ext/Module.bsl +++ b/src/CommonModules/МенеджерОбменаЧерезУниверсальныйФормат/Ext/Module.bsl @@ -1,10 +1,13 @@ #Область СлужебныйПрограммныйИнтерфейс #Область ПКПД -// Заполняет таблицу правил конвертации предопределенных данных. +// &После ЗаполнитьПравилаКонвертацииПредопределенныхДанных. +// Дополняет правило ПКПД «Перечисление_СтавкиНДС» значениями НДС22 и НДС22_122 +// для обмена crm3-dev → crm3-26 (EnterpriseData 1.8+). // // Параметры: -// НаправлениеОбмена - Строка - "Отправка" либо "Получение". -// ПравилаКонвертации - ТаблицаЗначений - таблица значений, в которую будут добавлены правила. +// НаправлениеОбмена - Строка - "Отправка" либо "Получение". +// ПравилаКонвертации - ТаблицаЗначений - таблица правил конвертации предопределённых данных. +// &После("ЗаполнитьПравилаКонвертацииПредопределенныхДанных") Процедура РК_ЗаполнитьПравилаКонвертацииПредопределенныхДанных(НаправлениеОбмена, ПравилаКонвертации) ПоискПравилКонвертации = ПравилаКонвертации.НайтиСтроки( @@ -39,11 +42,55 @@ #Область Синхронизация_crm3_dev_crm3_26 -// 01.07.2026 — синхронизация crm3-dev → crm3-26 (ПКО Справочник_Номенклатура_Получение). -// Суть: не менять способ учёта номенклатуры в целевой ИБ при обновлении существующих -// элементов. Перед типовой обработкой сохраняем снимок учётных реквизитов целевой базы, -// после — восстанавливаем их в объект записи (ВидНоменклатуры, ОсобенностьУчета и др.). +// Ограничения обмена номенклатурой и видами номенклатуры (crm3-dev → crm3-26). +// Существующие элементы: не перезаписывать складской/финансовый учёт из источника. +// Новые элементы: применить настройки учёта вида номенклатуры целевой ИБ. +// См. docs/transfer/Анализ_синхронизации_crm3-dev_crm3-26.md, §3.2. +// Возвращает список реквизитов номенклатуры, подлежащих защите от перезаписи при обмене. +// +// Возвращаемое значение: +// Строка - имена реквизитов через запятую для конструктора Структура. +// +Функция РК_УчетныеРеквизитыНоменклатурыДляЗащиты() + Возврат "ВидНоменклатуры, ОсобенностьУчета, ТипНоменклатуры, ИспользованиеХарактеристик," + + "ВладелецСерий, ВладелецХарактеристик, ГруппаФинансовогоУчета, СкладскаяГруппа"; +КонецФункции + +// Создаёт в параметрах конвертации соответствие для хранения снимков учётных реквизитов номенклатуры. +// +// Параметры: +// КомпонентыОбмена - Структура - контекст текущей сессии обмена (ПараметрыКонвертации). +// +Процедура РК_ИнициализироватьСнимкиУчетаНоменклатуры(КомпонентыОбмена) + Если Не КомпонентыОбмена.ПараметрыКонвертации.Свойство("РК_СнимкиУчетаНоменклатуры") Тогда + КомпонентыОбмена.ПараметрыКонвертации.Вставить("РК_СнимкиУчетаНоменклатуры", Новый Соответствие); + КонецЕсли; +КонецПроцедуры + +// Сохраняет снимок учётных реквизитов номенклатуры для последующего восстановления +// после типовой обработки и отложенного заполнения. +// +// Параметры: +// СсылкаНоменклатуры - СправочникСсылка.Номенклатура - элемент целевой ИБ. +// СнимокУчета - Структура - значения защищаемых реквизитов. +// КомпонентыОбмена - Структура - контекст текущей сессии обмена. +// +Процедура РК_СохранитьСнимокУчетаНоменклатуры(СсылкаНоменклатуры, СнимокУчета, КомпонентыОбмена) + РК_ИнициализироватьСнимкиУчетаНоменклатуры(КомпонентыОбмена); + КомпонентыОбмена.ПараметрыКонвертации.РК_СнимкиУчетаНоменклатуры.Вставить(СсылкаНоменклатуры, СнимокУчета); +КонецПроцедуры + +// &Перед ПКО_Справочник_Номенклатура_Получение_ПередЗаписьюПолученныхДанных. +// Для существующей в целевой ИБ номенклатуры сохраняет снимок учётных реквизитов +// до выполнения типового обработчика получения. +// +// Параметры: +// ПолученныеДанные - СправочникОбъект.Номенклатура - данные из пакета обмена. +// ДанныеИБ - СправочникОбъект.Номенклатура - существующий объект целевой ИБ; Неопределено для нового. +// КонвертацияСвойств - ТаблицаЗначений - правила конвертации свойств ПКО. +// КомпонентыОбмена - Структура - контекст текущей сессии обмена. +// &Перед("ПКО_Справочник_Номенклатура_Получение_ПередЗаписьюПолученныхДанных") Процедура РК_ПКО_Справочник_Номенклатура_Получение_ПередЗаписью_СохранитьУчет(ПолученныеДанные, ДанныеИБ, КонвертацияСвойств, КомпонентыОбмена) @@ -51,17 +98,31 @@ Возврат; КонецЕсли; - СнимокУчета = Новый Структура( - "ВидНоменклатуры, ОсобенностьУчета, ТипНоменклатуры, ИспользованиеХарактеристик, ВладелецСерий, ВладелецХарактеристик"); + СнимокУчета = Новый Структура(РК_УчетныеРеквизитыНоменклатурыДляЗащиты()); ЗаполнитьЗначенияСвойств(СнимокУчета, ДанныеИБ); ПолученныеДанные.ДополнительныеСвойства.Вставить("РК_СнимокУчетаНоменклатуры", СнимокУчета); + РК_СохранитьСнимокУчетаНоменклатуры(ДанныеИБ.Ссылка, СнимокУчета, КомпонентыОбмена); КонецПроцедуры +// &После ПКО_Справочник_Номенклатура_Получение_ПередЗаписьюПолученныхДанных. +// Для существующей номенклатуры восстанавливает учётные реквизиты целевой ИБ из снимка. +// Для новой номенклатуры заполняет складской и финансовый учёт по виду номенклатуры целевой ИБ. +// +// Параметры: +// ПолученныеДанные - СправочникОбъект.Номенклатура - данные из пакета обмена. +// ДанныеИБ - СправочникОбъект.Номенклатура - существующий объект целевой ИБ; Неопределено для нового. +// КонвертацияСвойств - ТаблицаЗначений - правила конвертации свойств ПКО. +// КомпонентыОбмена - Структура - контекст текущей сессии обмена. +// &После("ПКО_Справочник_Номенклатура_Получение_ПередЗаписьюПолученныхДанных") -Процедура РК_ПКО_Справочник_Номенклатура_Получение_ПередЗаписью_ВосстановитьУчет(ПолученныеДанные, ДанныеИБ, КонвертацияСвойств, КомпонентыОбмена) +Процедура РК_ПКО_Справочник_Номенклатура_Получение_ПередЗаписью_УчетПослеБазы(ПолученныеДанные, ДанныеИБ, КонвертацияСвойств, КомпонентыОбмена) Если ДанныеИБ = Неопределено Тогда + // Новая номенклатура: настройки складского и финансового учёта — из вида целевой ИБ. + Если ЗначениеЗаполнено(ПолученныеДанные.ВидНоменклатуры) Тогда + Справочники.Номенклатура.ЗаполнитьРеквизитыПоВидуНоменклатуры(ПолученныеДанные); + КонецЕсли; Возврат; КонецЕсли; @@ -73,15 +134,71 @@ КонецПроцедуры +// &ИзменениеИКонтроль ПКО_Справочник_ВидыНоменклатуры_ПередЗаписьюПолученныхДанных. +// Пропускает обновление видов номенклатуры, уже существующих в целевой ИБ +// (сопоставление по GUID сохраняется, учётные настройки целевой ИБ не меняются). +// +// Параметры: +// ПолученныеДанные - СправочникОбъект.ВидыНоменклатуры - данные из пакета обмена. +// ДанныеИБ - СправочникОбъект.ВидыНоменклатуры - существующий объект целевой ИБ; Неопределено для нового. +// КонвертацияСвойств - ТаблицаЗначений - правила конвертации свойств ПКО. +// КомпонентыОбмена - Структура - контекст текущей сессии обмена. +// +&ИзменениеИКонтроль("ПКО_Справочник_ВидыНоменклатуры_ПередЗаписьюПолученныхДанных") +Процедура РК_ПКО_Справочник_ВидыНоменклатуры_ПередЗаписьюПолученныхДанных(ПолученныеДанные, ДанныеИБ, КонвертацияСвойств, КомпонентыОбмена) + + #Вставка + Если ДанныеИБ <> Неопределено Тогда + ПолученныеДанные = Неопределено; + Возврат; + КонецЕсли; + #КонецВставки + + ДанныеДляЗаписиВИБ = ?(ДанныеИБ = Неопределено, ПолученныеДанные, ДанныеИБ); + + Если НЕ ЗначениеЗаполнено(ДанныеДляЗаписиВИБ.ВариантОформленияПродажи) Тогда + ДанныеДляЗаписиВИБ.ВариантОформленияПродажи = Перечисления.ВариантыОформленияПродажи.РеализацияТоваровУслуг; + КонецЕсли; + + Если НЕ ЗначениеЗаполнено(ДанныеДляЗаписиВИБ.ИспользованиеХарактеристик) Тогда + ДанныеДляЗаписиВИБ.ИспользованиеХарактеристик = Перечисления.ВариантыИспользованияХарактеристикНоменклатуры.НеИспользовать; + КонецЕсли; + + Если Не ЗначениеЗаполнено(ДанныеДляЗаписиВИБ.НастройкиКлючаЦенПоНоменклатуре) Тогда + ДанныеДляЗаписиВИБ.НастройкиКлючаЦенПоНоменклатуре = Перечисления.ВариантОтбораДляКлючаЦен.Использовать; + КонецЕсли; + + Если Не ЗначениеЗаполнено(ДанныеДляЗаписиВИБ.НастройкиКлючаЦенПоХарактеристике) Тогда + ДанныеДляЗаписиВИБ.НастройкиКлючаЦенПоХарактеристике = Перечисления.ВариантОтбораДляКлючаЦен.НеИспользовать; + КонецЕсли; + + Если Не ЗначениеЗаполнено(ДанныеДляЗаписиВИБ.НастройкиКлючаЦенПоСерии) Тогда + ДанныеДляЗаписиВИБ.НастройкиКлючаЦенПоСерии = Перечисления.ВариантОтбораДляКлючаЦен.НеИспользовать; + КонецЕсли; + + Если Не ЗначениеЗаполнено(ДанныеДляЗаписиВИБ.НастройкиКлючаЦенПоУпаковке) Тогда + ДанныеДляЗаписиВИБ.НастройкиКлючаЦенПоУпаковке = Перечисления.ВариантОтбораДляКлючаЦен.НеИспользовать; + КонецЕсли; + + Если Не ПолученныеДанные.ИспользоватьСерии = Истина Тогда + ПолученныеДанные.ИспользоватьСерии = ДанныеДляЗаписиВИБ.ИспользоватьСерии; + КонецЕсли; +КонецПроцедуры + +// &ИзменениеИКонтроль ПКО_Справочник_Склады_Получение_ПередЗаписьюПолученныхДанных. +// Пропускает обновление складов, уже существующих в целевой ИБ +// (сопоставление по GUID сохраняется, реквизиты целевого склада не меняются). +// +// Параметры: +// ПолученныеДанные - СправочникОбъект.Склады - данные из пакета обмена. +// ДанныеИБ - СправочникОбъект.Склады - существующий объект целевой ИБ; Неопределено для нового. +// КонвертацияСвойств - ТаблицаЗначений - правила конвертации свойств ПКО. +// КомпонентыОбмена - Структура - контекст текущей сессии обмена. +// &ИзменениеИКонтроль("ПКО_Справочник_Склады_Получение_ПередЗаписьюПолученныхДанных") Процедура РК_ПКО_Справочник_Склады_Получение_ПередЗаписьюПолученныхДанных(ПолученныеДанные, ДанныеИБ, КонвертацияСвойств, КомпонентыОбмена) #Вставка - // 01.07.2026 — синхронизация crm3-dev → crm3-26 (ПКО Справочник_Склады_Получение). - // Суть: не обновлять склады, уже существующие в целевой ИБ (ДанныеИБ заполнен, - // сопоставление по GUID сохраняется). Типовой обмен перезаписывал бы наименование, - // тип склада, контактную информацию данными из источника. - // Новые склады (ДанныеИБ = Неопределено) по-прежнему создаются при первой выгрузке. Если ДанныеИБ <> Неопределено Тогда ПолученныеДанные = Неопределено; Возврат; @@ -92,4 +209,177 @@ ПолученныеДанные.ДополнительныеСвойства, КомпонентыОбмена); КонецПроцедуры +// &После ОтложеннаяОбработка_ЗаполнитьНоменклатуру. +// Восстанавливает учётные реквизиты номенклатуры из снимков после типовой отложенной обработки, +// которая перезаписывает ИспользованиеХарактеристик значением из вида номенклатуры. +// +// Параметры: +// КомпонентыОбмена - Структура - контекст текущей сессии обмена (ПараметрыКонвертации.РК_СнимкиУчетаНоменклатуры). +// +&После("ОтложеннаяОбработка_ЗаполнитьНоменклатуру") +Процедура РК_ОтложеннаяОбработка_ВосстановитьУчетНоменклатуры(КомпонентыОбмена) + + Если Не КомпонентыОбмена.ПараметрыКонвертации.Свойство("РК_СнимкиУчетаНоменклатуры") Тогда + Возврат; + КонецЕсли; + + Снимки = КомпонентыОбмена.ПараметрыКонвертации.РК_СнимкиУчетаНоменклатуры; + Если Снимки.Количество() = 0 Тогда + Возврат; + КонецЕсли; + + Для Каждого КлючИЗначение Из Снимки Цикл + НоменклатураСсылка = КлючИЗначение.Ключ; + СнимокУчета = КлючИЗначение.Значение; + Если Не ОбщегоНазначения.СсылкаСуществует(НоменклатураСсылка) Тогда + Продолжить; + КонецЕсли; + НоменклатураОбъект = НоменклатураСсылка.ПолучитьОбъект(); + ЗаполнитьЗначенияСвойств(НоменклатураОбъект, СнимокУчета); + НоменклатураОбъект.ОбменДанными.Загрузка = Истина; + Попытка + НоменклатураОбъект.Записать(); + Исключение + ЗаписатьОшибкуВЖурналРегистрации(НоменклатураСсылка, + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()), КомпонентыОбмена); + КонецПопытки; + КонецЦикла; + +КонецПроцедуры + +// Возвращает владельца серий для вида номенклатуры в целевой ИБ +// (с учётом НастройкиСерийБерутсяИзДругогоВидаНоменклатуры). +// +// Параметры: +// ВидНоменклатуры - СправочникСсылка.ВидыНоменклатуры - вид из пакета обмена или номенклатуры. +// +// Возвращаемое значение: +// СправочникСсылка.ВидыНоменклатуры - вид-владелец для справочника СерииНоменклатуры. +// +Функция РК_ВладелецСерийДляВидаНоменклатуры(ВидНоменклатуры) + + Если Не ЗначениеЗаполнено(ВидНоменклатуры) Тогда + Возврат Справочники.ВидыНоменклатуры.ПустаяСсылка(); + КонецЕсли; + + НастройкиСерий = Справочники.ВидыНоменклатуры.НастройкиИспользованияСерий(ВидНоменклатуры); + ВладелецСерий = НастройкиСерий.ВладелецСерий; + Если Не ЗначениеЗаполнено(ВладелецСерий) Тогда + ВладелецСерий = ВидНоменклатуры; + КонецЕсли; + + Возврат ВладелецСерий; + +КонецФункции + +// &После ДобавитьПКО_Справочник_СерииНоменклатуры. +// Подключает обработчик проверки владельца серии при получении из пакета обмена. +// +// Параметры: +// ПравилаКонвертации - ТаблицаЗначений - таблица правил конвертации объектов. +// +&После("ДобавитьПКО_Справочник_СерииНоменклатуры") +Процедура РК_ДобавитьПКО_Справочник_СерииНоменклатуры_УстановитьПередЗаписью(ПравилаКонвертации) + + СтрокиПКО = ПравилаКонвертации.НайтиСтроки(Новый Структура("ИмяПКО", "Справочник_СерииНоменклатуры")); + Если СтрокиПКО.Количество() = 0 Тогда + Возврат; + КонецЕсли; + + СтрокиПКО[0].ПередЗаписьюПолученныхДанных = "РК_ПКО_Справочник_СерииНоменклатуры_ПередЗаписьюПолученныхДанных"; + +КонецПроцедуры + +// ПКО Справочник_СерииНоменклатуры — ПередЗаписьюПолученныхДанных. +// Проверяет и нормализует привязку серии к виду-владельцу в целевой ИБ. +// При несовпадении владельца у сопоставленной по полям поиска серии — пропуск записи. +// +// Параметры: +// ПолученныеДанные - СправочникОбъект.СерииНоменклатуры - данные из пакета обмена. +// ДанныеИБ - СправочникОбъект.СерииНоменклатуры - существующий объект; Неопределено для нового. +// КонвертацияСвойств - ТаблицаЗначений - правила конвертации свойств ПКО. +// КомпонентыОбмена - Структура - контекст текущей сессии обмена. +// +Процедура РК_ПКО_Справочник_СерииНоменклатуры_ПередЗаписьюПолученныхДанных(ПолученныеДанные, ДанныеИБ, КонвертацияСвойств, КомпонентыОбмена) + + Если ПолученныеДанные = Неопределено Тогда + Возврат; + КонецЕсли; + + Если Не ЗначениеЗаполнено(ПолученныеДанные.ВидНоменклатуры) Тогда + Возврат; + КонецЕсли; + + КорректныйВладелец = РК_ВладелецСерийДляВидаНоменклатуры(ПолученныеДанные.ВидНоменклатуры); + Если Не ЗначениеЗаполнено(КорректныйВладелец) Тогда + Возврат; + КонецЕсли; + + СсылкаДляЖурнала = ?(ДанныеИБ = Неопределено, ПолученныеДанные.ПолучитьСсылкуНового(), ДанныеИБ.Ссылка); + + Если ДанныеИБ <> Неопределено Тогда + + Если ЗначениеЗаполнено(ДанныеИБ.ВидНоменклатуры) + И ДанныеИБ.ВидНоменклатуры <> КорректныйВладелец + И ПолученныеДанные.ВидНоменклатуры <> ДанныеИБ.ВидНоменклатуры Тогда + + ТекстОшибки = СтрШаблон( + "Неверная привязка серии по владельцу: в ИБ %1, из пакета (норм.) %2, наименование ""%3"", номер ""%4"".", + ДанныеИБ.ВидНоменклатуры, + КорректныйВладелец, + ПолученныеДанные.Наименование, + ПолученныеДанные.Номер); + ЗаписатьОшибкуВЖурналРегистрации(СсылкаДляЖурнала, ТекстОшибки, КомпонентыОбмена, + НСтр("ru = 'записать серию номенклатуры'"), УровеньЖурналаРегистрации.Предупреждение); + ПолученныеДанные = Неопределено; + Возврат; + + КонецЕсли; + + Если ЗначениеЗаполнено(ДанныеИБ.ВидНоменклатуры) Тогда + ПолученныеДанные.ВидНоменклатуры = ДанныеИБ.ВидНоменклатуры; + Иначе + ПолученныеДанные.ВидНоменклатуры = КорректныйВладелец; + КонецЕсли; + + Иначе + + ПолученныеДанные.ВидНоменклатуры = КорректныйВладелец; + + Запрос = Новый Запрос; + Запрос.Текст = + "ВЫБРАТЬ ПЕРВЫЕ 1 + | Серии.Ссылка КАК Ссылка + |ИЗ + | Справочник.СерииНоменклатуры КАК Серии + |ГДЕ + | Серии.ВидНоменклатуры = &Владелец + | И НЕ Серии.ПометкаУдаления + | И (Серии.Наименование = &Наименование + | ИЛИ Серии.Номер = &Номер + | И &НомерЗаполнен)"; + Запрос.УстановитьПараметр("Владелец", КорректныйВладелец); + Запрос.УстановитьПараметр("Наименование", ПолученныеДанные.Наименование); + Запрос.УстановитьПараметр("Номер", ПолученныеДанные.Номер); + Запрос.УстановитьПараметр("НомерЗаполнен", ЗначениеЗаполнено(ПолученныеДанные.Номер)); + + Выборка = Запрос.Выполнить().Выбрать(); + Если Выборка.Следующий() + И Выборка.Ссылка <> СсылкаДляЖурнала Тогда + + ТекстОшибки = СтрШаблон( + "Серия с наименованием ""%1"" уже существует у владельца %2 (%3), GUID отличается от пакета.", + ПолученныеДанные.Наименование, + КорректныйВладелец, + Выборка.Ссылка); + ЗаписатьОшибкуВЖурналРегистрации(СсылкаДляЖурнала, ТекстОшибки, КомпонентыОбмена, + НСтр("ru = 'создать серию номенклатуры'"), УровеньЖурналаРегистрации.Предупреждение); + ПолученныеДанные = Неопределено; + + КонецЕсли; + + КонецЕсли; + +КонецПроцедуры + #КонецОбласти