diff --git a/CHANGELOG.md b/CHANGELOG.md
index fbcd729..dd68453 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,13 @@
---
+## 1.3.1.123 (2026-10-07)
+
+### Fix: журнал при fallback партнёра ED ([#67](https://git.p7net.ru/rhana/crm3-migration/issues/67) comment-1632)
+
+- `ЗаписатьОшибкуВЖурналРегистрации` больше не вызывается с `Неопределено` (падение `.Метаданные` при create отсутствующего партнёра).
+- В предупреждение попадают meta/results `partners/load`; `update_existing=true` чтобы дописать `РК_КодСтаройБазы` при match по имени.
+
## 1.3.1.122 (2026-10-07)
### ED: fallback партнёра через Transfer API ([#67](https://git.p7net.ru/rhana/crm3-migration/issues/67))
diff --git a/VERSION b/VERSION
index 41f7d39..9f21e6a 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.3.1.122
+1.3.1.123
diff --git a/src/CommonModules/МенеджерОбменаЧерезУниверсальныйФормат/Ext/Module.bsl b/src/CommonModules/МенеджерОбменаЧерезУниверсальныйФормат/Ext/Module.bsl
index 11d3b49..4a0dbca 100644
--- a/src/CommonModules/МенеджерОбменаЧерезУниверсальныйФормат/Ext/Module.bsl
+++ b/src/CommonModules/МенеджерОбменаЧерезУниверсальныйФормат/Ext/Module.bsl
@@ -1336,7 +1336,7 @@
ПартнерСсылка = РК_НайтиПартнераПоКодуСтаройБазы(КодПартнера);
Если Не ЗначениеЗаполнено(ПартнерСсылка) Тогда
- ПартнерСсылка = РК_ОбеспечитьПартнераЧерезTransferAPI(КодПартнера, КомпонентыОбмена);
+ ПартнерСсылка = РК_ОбеспечитьПартнераЧерезTransferAPI(КодПартнера, КомпонентыОбмена, Объект);
КонецЕсли;
Если Не ЗначениеЗаполнено(ПартнерСсылка) Тогда
@@ -1381,13 +1381,20 @@
// Export с исходной ИБ (константа РК_РабочееПодключениеЧерезАПИ) + load через РВС_TransferAPIПартнеры.
// Как sync в transfer_partners.py для одного кода. Контрагентов из пакета не создаём (грузятся ED).
//
-Функция РК_ОбеспечитьПартнераЧерезTransferAPI(КодПартнера, КомпонентыОбмена)
+// Параметры:
+// КодПартнера - Строка
+// КомпонентыОбмена - Структура
+// ОбъектКонтрагента - СправочникОбъект.Контрагенты, Неопределено — для журнала (нельзя Неопределено в ЗаписатьОшибкуВЖурналРегистрации).
+//
+Функция РК_ОбеспечитьПартнераЧерезTransferAPI(КодПартнера, КомпонентыОбмена, ОбъектКонтрагента = Неопределено)
КодПартнера = СокрЛП(КодПартнера);
Если ПустаяСтрока(КодПартнера) Тогда
Возврат Неопределено;
КонецЕсли;
+ СсылкаДляЖурнала = РК_СсылкаДляЖурналаКонтрагента(ОбъектКонтрагента);
+
РК_ИнициализироватьКешПартнеровПоКоду(КомпонентыОбмена);
Если КомпонентыОбмена <> Неопределено
И КомпонентыОбмена.Свойство("ПараметрыКонвертации")
@@ -1413,24 +1420,22 @@
КонецПопытки;
Если Не ЗначениеЗаполнено(Подключение) Тогда
- ЗаписатьОшибкуВЖурналРегистрации(
- Неопределено,
+ РК_ЗаписатьПредупреждениеПартнераTransferAPI(
+ СсылкаДляЖурнала,
"РК_РабочееПодключениеЧерезАПИ не заполнено — нельзя выгрузить партнёра "
+ КодПартнера + " из исходной ИБ.",
КомпонентыОбмена,
- НСтр("ru = 'загрузить партнёра через Transfer API'"),
- УровеньЖурналаРегистрации.Предупреждение);
+ НСтр("ru = 'загрузить партнёра через Transfer API'"));
Возврат Неопределено;
КонецЕсли;
Если Метаданные.ОбщиеМодули.Найти("РВС_TransferAPIПартнеры") = Неопределено Тогда
- ЗаписатьОшибкуВЖурналРегистрации(
- Неопределено,
+ РК_ЗаписатьПредупреждениеПартнераTransferAPI(
+ СсылкаДляЖурнала,
"Модуль РВС_TransferAPIПартнеры недоступен (нужен ws-rhana) — партнёр "
+ КодПартнера + " не загружен.",
КомпонентыОбмена,
- НСтр("ru = 'загрузить партнёра через Transfer API'"),
- УровеньЖурналаРегистрации.Предупреждение);
+ НСтр("ru = 'загрузить партнёра через Transfer API'"));
Возврат Неопределено;
КонецЕсли;
@@ -1445,30 +1450,29 @@
Попытка
ОтветExport = РК_ОбменСВнешнейБазой.ПартнерыВнешнейБазы(Подключение, ПараметрыExport);
Исключение
- ЗаписатьОшибкуВЖурналРегистрации(
- Неопределено,
+ РК_ЗаписатьПредупреждениеПартнераTransferAPI(
+ СсылкаДляЖурнала,
"partners/export код=" + КодПартнера + ": " + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()),
КомпонентыОбмена,
- НСтр("ru = 'выгрузить партнёра из исходной ИБ'"),
- УровеньЖурналаРегистрации.Предупреждение);
+ НСтр("ru = 'выгрузить партнёра из исходной ИБ'"));
Возврат Неопределено;
КонецПопытки;
ПартнерыПакета = РК_ЗначениеСвойстваОтвета(ОтветExport, "partners");
Если ТипЗнч(ПартнерыПакета) <> Тип("Массив") Или ПартнерыПакета.Количество() = 0 Тогда
- ЗаписатьОшибкуВЖурналРегистрации(
- Неопределено,
+ РК_ЗаписатьПредупреждениеПартнераTransferAPI(
+ СсылкаДляЖурнала,
"partners/export: партнёр с кодом " + КодПартнера + " не найден в исходной ИБ.",
КомпонентыОбмена,
- НСтр("ru = 'выгрузить партнёра из исходной ИБ'"),
- УровеньЖурналаРегистрации.Предупреждение);
+ НСтр("ru = 'выгрузить партнёра из исходной ИБ'"));
Возврат Неопределено;
КонецЕсли;
ПараметрыLoad = Новый Структура;
ПараметрыLoad.Вставить("dry_run", Ложь);
ПараметрыLoad.Вставить("create_missing", Истина);
- ПараметрыLoad.Вставить("update_existing", Ложь);
+ // renew old_code даже при match по имени (иначе РК_КодСтаройБазы может не появиться).
+ ПараметрыLoad.Вставить("update_existing", Истина);
ПараметрыLoad.Вставить("bind_contractors", Ложь);
ПараметрыLoad.Вставить("add_contacts", Ложь);
ПараметрыLoad.Вставить("old_code_mode", "renew");
@@ -1478,12 +1482,11 @@
МодульПартнеров = ОбщегоНазначения.ОбщийМодуль("РВС_TransferAPIПартнеры");
ОтветLoad = МодульПартнеров.ВыполнитьЗагрузку(ПараметрыLoad);
Исключение
- ЗаписатьОшибкуВЖурналРегистрации(
- Неопределено,
+ РК_ЗаписатьПредупреждениеПартнераTransferAPI(
+ СсылкаДляЖурнала,
"partners/load код=" + КодПартнера + ": " + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()),
КомпонентыОбмена,
- НСтр("ru = 'загрузить партнёра в целевую ИБ'"),
- УровеньЖурналаРегистрации.Предупреждение);
+ НСтр("ru = 'загрузить партнёра в целевую ИБ'"));
Возврат Неопределено;
КонецПопытки;
@@ -1493,12 +1496,12 @@
КонецЕсли;
Если Не ЗначениеЗаполнено(ПартнерСсылка) Тогда
- ЗаписатьОшибкуВЖурналРегистрации(
- Неопределено,
- "partners/load: после загрузки партнёр с РК_КодСтаройБазы=" + КодПартнера + " не найден.",
+ РК_ЗаписатьПредупреждениеПартнераTransferAPI(
+ СсылкаДляЖурнала,
+ "partners/load: после загрузки партнёр с РК_КодСтаройБазы=" + КодПартнера
+ + " не найден. " + РК_КраткоОтветPartnersLoad(ОтветLoad),
КомпонентыОбмена,
- НСтр("ru = 'загрузить партнёра в целевую ИБ'"),
- УровеньЖурналаРегистрации.Предупреждение);
+ НСтр("ru = 'загрузить партнёра в целевую ИБ'"));
Возврат Неопределено;
КонецЕсли;
@@ -1507,6 +1510,83 @@
КонецФункции
+Функция РК_СсылкаДляЖурналаКонтрагента(ОбъектКонтрагента)
+
+ Если ОбъектКонтрагента = Неопределено Тогда
+ Возврат Справочники.Контрагенты.ПустаяСсылка();
+ КонецЕсли;
+
+ Попытка
+ Если ЗначениеЗаполнено(ОбъектКонтрагента.Ссылка) Тогда
+ Возврат ОбъектКонтрагента.Ссылка;
+ КонецЕсли;
+ Исключение
+ КонецПопытки;
+
+ Попытка
+ СсылкаНового = ОбъектКонтрагента.ПолучитьСсылкуНового();
+ Если ЗначениеЗаполнено(СсылкаНового) Тогда
+ Возврат СсылкаНового;
+ КонецЕсли;
+ Исключение
+ КонецПопытки;
+
+ Возврат Справочники.Контрагенты.ПустаяСсылка();
+
+КонецФункции
+
+// ЗаписатьОшибкуВЖурналРегистрации требует объектную ссылку (.Метаданные) — Неопределено недопустим.
+//
+Процедура РК_ЗаписатьПредупреждениеПартнераTransferAPI(СсылкаДляЖурнала, ТекстОшибки, КомпонентыОбмена, ОписаниеДействия)
+
+ Если Не ЗначениеЗаполнено(СсылкаДляЖурнала) Тогда
+ СсылкаДляЖурнала = Справочники.Контрагенты.ПустаяСсылка();
+ КонецЕсли;
+
+ ЗаписатьОшибкуВЖурналРегистрации(
+ СсылкаДляЖурнала,
+ ТекстОшибки,
+ КомпонентыОбмена,
+ ОписаниеДействия,
+ УровеньЖурналаРегистрации.Предупреждение);
+
+КонецПроцедуры
+
+Функция РК_КраткоОтветPartnersLoad(ОтветLoad)
+
+ Части = Новый Массив;
+ Мета = РК_ЗначениеСвойстваОтвета(ОтветLoad, "meta");
+ Если Мета <> Неопределено Тогда
+ Части.Добавить(СтрШаблон(
+ "meta created=%1 updated=%2 skipped=%3 errors=%4",
+ РК_ЗначениеСвойстваОтвета(Мета, "created", 0),
+ РК_ЗначениеСвойстваОтвета(Мета, "updated", 0),
+ РК_ЗначениеСвойстваОтвета(Мета, "skipped", 0),
+ РК_ЗначениеСвойстваОтвета(Мета, "errors", 0)));
+ КонецЕсли;
+
+ Результаты = РК_ЗначениеСвойстваОтвета(ОтветLoad, "results");
+ Если ТипЗнч(Результаты) = Тип("Массив") Тогда
+ Индекс = 0;
+ Для Каждого СтрокаРез Из Результаты Цикл
+ Индекс = Индекс + 1;
+ Если Индекс > 3 Тогда
+ Части.Добавить("…");
+ Прервать;
+ КонецЕсли;
+ Части.Добавить(СтрШаблон(
+ "[%1] status=%2 action=%3 message=%4",
+ Индекс,
+ РК_ЗначениеСвойстваОтвета(СтрокаРез, "status", ""),
+ РК_ЗначениеСвойстваОтвета(СтрокаРез, "action", ""),
+ РК_ЗначениеСвойстваОтвета(СтрокаРез, "message", "")));
+ КонецЦикла;
+ КонецЕсли;
+
+ Возврат СтрСоединить(Части, "; ");
+
+КонецФункции
+
Процедура РК_ЗапомнитьПартнераВКешеСессии(КомпонентыОбмена, КодПартнера, ПартнерСсылка)
РК_ИнициализироватьКешПартнеровПоКоду(КомпонентыОбмена);
diff --git a/src/Configuration.xml b/src/Configuration.xml
index 7e28327..c31df56 100644
--- a/src/Configuration.xml
+++ b/src/Configuration.xml
@@ -62,7 +62,7 @@
Role.РК_ОсновнаяРоль
- 1.3.1.122
+ 1.3.1.123
Language.Русский