Обмен: досоздание объектов расчётов по договорам (1.3.0.40).

Типовой механизм UT 11.5 может не создать ОР при обмене crm3-dev→crm3-26; добавлен fallback через СоздатьЭлемент после отложенной обработки.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
4 changed files with 245 additions and 4 deletions
@@ -1,4 +1,4 @@
#Область СлужебныйПрограммныйИнтерфейс
#Область СлужебныйПрограммныйИнтерфейс
#Область ПКПД
// &После ЗаполнитьПравилаКонвертацииПредопределенныхДанных.
// Дополняет правило ПКПД «Перечисление_СтавкиНДС» значениями НДС22 и НДС22_122
@@ -443,4 +443,226 @@
КонецПроцедуры
// --- Объекты расчётов (crm3-dev → crm3-26) ---
// В UT 11.5 ОбъектыРасчетов — отдельный справочник; в XDTO 1.8 не передаётся.
// Типовой ВзаиморасчетыСервер.ПередЗаписью может не создать ОР (СоздатьПоКлючу, пустой партнёр).
// См. docs/transfer/План_синхронизации_2026-07-06_Учет.md (У1.1), Код_создания_объектов_расчетов_договоров.bsl.
// Возвращает партнёра и контрагента для договора: из договора, подсказок или последнего заказа.
//
// Параметры:
// ДоговорСсылка - СправочникСсылка.ДоговорыКонтрагентов.
// ПартнерПодсказка - СправочникСсылка.Партнеры, Неопределено.
// КонтрагентПодсказка - СправочникСсылка.Контрагенты, Неопределено.
//
// Возвращаемое значение:
// Структура - Партнер, Контрагент (могут остаться пустыми).
//
Функция РК_ПартнерКонтрагентДляДоговора(ДоговорСсылка, ПартнерПодсказка = Неопределено, КонтрагентПодсказка = Неопределено)
Результат = Новый Структура("Партнер, Контрагент");
Если Не ЗначениеЗаполнено(ДоговорСсылка) Тогда
Возврат Результат;
КонецЕсли;
РеквизитыДоговора = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(ДоговорСсылка, "Партнер, Контрагент");
Партнер = РеквизитыДоговора.Партнер;
Контрагент = РеквизитыДоговора.Контрагент;
Если ЗначениеЗаполнено(ПартнерПодсказка) Тогда
Партнер = ПартнерПодсказка;
КонецЕсли;
Если ЗначениеЗаполнено(КонтрагентПодсказка) Тогда
Контрагент = КонтрагентПодсказка;
КонецЕсли;
Если Не ЗначениеЗаполнено(Контрагент) И ЗначениеЗаполнено(Партнер) Тогда
Контрагент = ПартнерыИКонтрагенты.ПолучитьКонтрагентаПартнераПоУмолчанию(Партнер);
КонецЕсли;
Если Не ЗначениеЗаполнено(Партнер) И ЗначениеЗаполнено(Контрагент) Тогда
Партнер = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Контрагент, "Партнер");
КонецЕсли;
Если Не ЗначениеЗаполнено(Партнер) ИЛИ Не ЗначениеЗаполнено(Контрагент) Тогда
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| Зак.Партнер КАК Партнер,
| Зак.Контрагент КАК Контрагент
|ИЗ
| Документ.ЗаказКлиента КАК Зак
|ГДЕ
| Зак.Договор = &Договор
| И НЕ Зак.ПометкаУдаления
|УПОРЯДОЧИТЬ ПО
| Зак.Дата УБЫВ";
Запрос.УстановитьПараметр("Договор", ДоговорСсылка);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
Если Не ЗначениеЗаполнено(Партнер) Тогда
Партнер = Выборка.Партнер;
КонецЕсли;
Если Не ЗначениеЗаполнено(Контрагент) Тогда
Контрагент = Выборка.Контрагент;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Не ЗначениеЗаполнено(Контрагент) И ЗначениеЗаполнено(Партнер) Тогда
Контрагент = ПартнерыИКонтрагенты.ПолучитьКонтрагентаПартнераПоУмолчанию(Партнер);
КонецЕсли;
Результат.Партнер = Партнер;
Результат.Контрагент = Контрагент;
Возврат Результат;
КонецФункции
// Создаёт элемент справочника ОбъектыРасчетов для договора, если его ещё нет.
// Использует СоздатьЭлемент (не СоздатьПоКлючу — падает на договорах из обмена).
//
// Параметры:
// ДоговорСсылка - СправочникСсылка.ДоговорыКонтрагентов.
// Партнер - СправочникСсылка.Партнеры.
// Контрагент - СправочникСсылка.Контрагенты.
// КомпонентыОбмена - Структура - контекст обмена (для журнала).
//
// Возвращаемое значение:
// СправочникСсылка.ОбъектыРасчетов - созданный или найденный ОР; пустая ссылка при ошибке.
//
Функция РК_ОбеспечитьОбъектРасчетовПоДоговору(ДоговорСсылка, Партнер, Контрагент, КомпонентыОбмена)
ПустаяСсылкаОР = Справочники.ОбъектыРасчетов.ПустаяСсылка();
Если Не ЗначениеЗаполнено(ДоговорСсылка) Или Не ОбщегоНазначения.СсылкаСуществует(ДоговорСсылка) Тогда
Возврат ПустаяСсылкаОР;
КонецЕсли;
Если Не ЗначениеЗаполнено(Партнер) Или Не ЗначениеЗаполнено(Контрагент) Тогда
Возврат ПустаяСсылкаОР;
КонецЕсли;
Организация = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(ДоговорСсылка, "Организация");
Если Не ЗначениеЗаполнено(Организация) Тогда
Возврат ПустаяСсылкаОР;
КонецЕсли;
Валюта = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(ДоговорСсылка, "ВалютаВзаиморасчетов");
Если Не ЗначениеЗаполнено(Валюта) Тогда
Валюта = Константы.ВалютаРегламентированногоУчета.Получить();
КонецЕсли;
КритерииОР = ОбъектыРасчетовСервер.ДополнительныеКритерииПоиска();
КритерииОР.Партнер = Партнер;
КритерииОР.Контрагент = Контрагент;
КритерииОР.ВалютаВзаиморасчетов = Валюта;
КритерииОР.ВернутьПервый = Истина;
СсылкаОР = ОбъектыРасчетовСервер.ПолучитьОбъектРасчетовПоСсылке(
ДоговорСсылка,
Организация,
Перечисления.ТипыРасчетовСПартнерами.РасчетыСКлиентом,
КритерииОР);
Если ЗначениеЗаполнено(СсылкаОР) Тогда
Возврат СсылкаОР;
КонецЕсли;
Попытка
НовыйОР = Справочники.ОбъектыРасчетов.СоздатьЭлемент();
НовыйОР.Объект = ДоговорСсылка;
НовыйОР.Организация = Организация;
НовыйОР.Контрагент = Контрагент;
НовыйОР.Партнер = Партнер;
НовыйОР.ТипРасчетов = Перечисления.ТипыРасчетовСПартнерами.РасчетыСКлиентом;
НовыйОР.ВалютаВзаиморасчетов = Валюта;
НовыйОР.Договор = ДоговорСсылка;
НовыйОР.Записать();
Возврат НовыйОР.Ссылка;
Исключение
ТекстОшибки = СтрШаблон(
"Не удалось создать объект расчётов для договора %1: %2",
ДоговорСсылка,
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
ЗаписатьОшибкуВЖурналРегистрации(ДоговорСсылка, ТекстОшибки, КомпонентыОбмена,
НСтр("ru = 'создать объект расчётов по договору'"), УровеньЖурналаРегистрации.Предупреждение);
Возврат ПустаяСсылкаОР;
КонецПопытки;
КонецФункции
// &После ПКО_Справочник_ДоговорыКонтрагентов_Получение_ПередЗаписьюПолученныхДанных.
// Дозаполняет партнёра на договоре из контрагента до записи в ИБ.
//
&После("ПКО_Справочник_ДоговорыКонтрагентов_Получение_ПередЗаписьюПолученныхДанных")
Процедура РК_ПКО_ДоговорыКонтрагентов_ДозаполнитьПартнера(ПолученныеДанные, ДанныеИБ, КонвертацияСвойств, КомпонентыОбмена)
Если Не РК_ЭтоОбменС_Crm3Dev(КомпонентыОбмена) Тогда
Возврат;
КонецЕсли;
Если ПолученныеДанные = Неопределено Тогда
Возврат;
КонецЕсли;
Если Не ЗначениеЗаполнено(ПолученныеДанные.Партнер) И ЗначениеЗаполнено(ПолученныеДанные.Контрагент) Тогда
ПолученныеДанные.Партнер = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(ПолученныеДанные.Контрагент, "Партнер");
КонецЕсли;
Если Не ЗначениеЗаполнено(ПолученныеДанные.Контрагент) И ЗначениеЗаполнено(ПолученныеДанные.Партнер) Тогда
ПолученныеДанные.Контрагент = ПартнерыИКонтрагенты.ПолучитьКонтрагентаПартнераПоУмолчанию(ПолученныеДанные.Партнер);
КонецЕсли;
КонецПроцедуры
// &После ОтложеннаяОбработка_СоздатьОбновитьОбъектыРасчетов.
// Досоздаёт объекты расчётов по договорам из пакета обмена, если типовой механизм их пропустил.
//
&После("ОтложеннаяОбработка_СоздатьОбновитьОбъектыРасчетов")
Процедура РК_ОтложеннаяОбработка_ДосоздатьОбъектыРасчетов(КомпонентыОбмена)
Если Не РК_ЭтоОбменС_Crm3Dev(КомпонентыОбмена) Тогда
Возврат;
КонецЕсли;
ДоговорыКОбработке = Новый Соответствие;
Для Каждого ЗагруженныйОбъект Из КомпонентыОбмена.ЗагруженныеОбъекты Цикл
СсылкаНаОбъект = ЗагруженныйОбъект.СсылкаНаОбъект;
ТипСсылки = ТипЗнч(СсылкаНаОбъект);
Если ТипСсылки = Тип("СправочникСсылка.ДоговорыКонтрагентов") Тогда
ДоговорыКОбработке.Вставить(СсылкаНаОбъект, Новый Структура("Партнер, Контрагент"));
ИначеЕсли ТипСсылки = Тип("ДокументСсылка.ЗаказКлиента") Тогда
РеквизитыЗаказа = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(СсылкаНаОбъект, "Договор, Партнер, Контрагент");
Если ЗначениеЗаполнено(РеквизитыЗаказа.Договор) Тогда
Подсказки = Новый Структура("Партнер, Контрагент", РеквизитыЗаказа.Партнер, РеквизитыЗаказа.Контрагент);
ДоговорыКОбработке.Вставить(РеквизитыЗаказа.Договор, Подсказки);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Для Каждого КлючИЗначение Из ДоговорыКОбработке Цикл
ДоговорСсылка = КлючИЗначение.Ключ;
Подсказки = КлючИЗначение.Значение;
Участники = РК_ПартнерКонтрагентДляДоговора(
ДоговорСсылка,
Подсказки.Партнер,
Подсказки.Контрагент);
РК_ОбеспечитьОбъектРасчетовПоДоговору(
ДоговорСсылка,
Участники.Партнер,
Участники.Контрагент,
КомпонентыОбмена);
КонецЦикла;
КонецПроцедуры
#КонецОбласти
+2 -2
View File
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8"?>
<MetaDataObject xmlns="http://v8.1c.ru/8.3/MDClasses" xmlns:app="http://v8.1c.ru/8.2/managed-application/core" xmlns:cfg="http://v8.1c.ru/8.1/data/enterprise/current-config" xmlns:cmi="http://v8.1c.ru/8.2/managed-application/cmi" xmlns:ent="http://v8.1c.ru/8.1/data/enterprise" xmlns:lf="http://v8.1c.ru/8.2/managed-application/logform" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows" xmlns:xen="http://v8.1c.ru/8.3/xcf/enums" xmlns:xpr="http://v8.1c.ru/8.3/xcf/predef" xmlns:xr="http://v8.1c.ru/8.3/xcf/readable" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.20">
<Configuration uuid="ef31d55b-3788-4972-affb-b7aefd3838aa">
<InternalInfo>
@@ -62,7 +62,7 @@
<xr:Item xsi:type="xr:MDObjectRef">Role.РК_ОсновнаяРоль</xr:Item>
</DefaultRoles>
<Vendor/>
<Version>1.3.0.39</Version>
<Version>1.3.0.40</Version>
<DefaultStyle/>
<DefaultLanguage>Language.Русский</DefaultLanguage>
<BriefInformation/>