Загрузка данных
////////////////////////////////////////////////////////////////////////////
// Расширение общего модуля менеджера обмена (БП 3.0.191, формат 1.22)
//
// Назначение: несколько документов "Реализация товаров и услуг" с видом
// операции "Передача на комиссию", пришедших из УТ за один сеанс обмена,
// загружаются в БП как ОДИН документ.
//
// Механика: первый документ группы грузится штатно. У второго и последующих
// в ПОД подменяются ключевые свойства (Ссылка/Дата/Номер) на значения первого,
// поэтому штатная идентификация находит уже записанный документ и обновляет
// его. Табличная часть при этом не замещается, а дополняется.
//
// Перехват идёт через экспортный диспетчер ВыполнитьПроцедуруМодуляМенеджера,
// сами обработчики ПОД/ПКО в модуле не экспортные.
////////////////////////////////////////////////////////////////////////////////
#Область НастройкиОтбора
// ИНН комиссионера, передачи к которому нужно сворачивать.
// Если комиссионеров несколько — заменить на список.
Функция КМ_ИННКомиссионера()
Возврат "9714053621"; // ООО "РВБ" (Wildberries)
КонецФункции
#КонецОбласти
#Область Перехваты
&Перед("ВыполнитьПроцедуруМодуляМенеджера")
Процедура КМ_Перед_ВыполнитьПроцедуруМодуляМенеджера(ИмяПроцедуры, Параметры)
Если ИмяПроцедуры <> "ПКО_Документ_РеализацияТоваровУслуг_ПередЗаписьюПолученныхДанных" Тогда
Возврат;
КонецЕсли;
// ДанныеИБ = Неопределено означает, что документа в базе ещё нет:
// это первый документ группы, накапливать нечего.
Если Параметры.ДанныеИБ = Неопределено Тогда
Возврат;
КонецЕсли;
// Запоминаем строки, которые сейчас лежат в базе, — типовой обработчик
// ниже по стеку их затрёт строками нового документа.
Хранилище = КМ_Хранилище(Параметры.КомпонентыОбмена);
Хранилище.Вставить("НакопленныеТовары", Параметры.ДанныеИБ.Товары.Выгрузить());
КонецПроцедуры
&После("ВыполнитьПроцедуруМодуляМенеджера")
Процедура КМ_После_ВыполнитьПроцедуруМодуляМенеджера(ИмяПроцедуры, Параметры)
Если ИмяПроцедуры = "ПОД_Документ_РеализацияТоваровУслуг_ПриОбработке" Тогда
КМ_ПодменитьКлючевыеСвойства(Параметры.ОбъектОбработки, Параметры.КомпонентыОбмена);
ИначеЕсли ИмяПроцедуры = "ПКО_Документ_РеализацияТоваровУслуг_ПередЗаписьюПолученныхДанных" Тогда
КМ_ОбъединитьТовары(Параметры.ДанныеИБ, Параметры.КомпонентыОбмена);
КонецЕсли;
КонецПроцедуры
#КонецОбласти
#Область ПодменаКлючевыхСвойств
Процедура КМ_ПодменитьКлючевыеСвойства(ДанныеXDTO, КомпонентыОбмена)
// Загрузка объекта как значения чужого свойства — трогать нельзя
// (аналог типовой ЭтоЗагрузкаКлючевыхСвойств).
Если ДанныеXDTO.Количество() = 1 Тогда
Возврат;
КонецЕсли;
Если Не КМ_ЭтоСворачиваемаяПередача(ДанныеXDTO) Тогда
Возврат;
КонецЕсли;
КлючГруппы = КМ_КлючГруппы(ДанныеXDTO);
Если Не ЗначениеЗаполнено(КлючГруппы) Тогда
Возврат;
КонецЕсли;
Хранилище = КМ_Хранилище(КомпонентыОбмена);
Лидер = Хранилище.Лидеры.Получить(КлючГруппы);
Если Лидер = Неопределено Тогда
// Первый документ группы. Грузится штатно, запоминаем его ключевые свойства.
Лидер = Новый Структура("Ссылка, Дата, Номер",
ДанныеXDTO.КлючевыеСвойства.Ссылка,
ДанныеXDTO.КлючевыеСвойства.Дата,
ДанныеXDTO.КлючевыеСвойства.Номер);
Хранилище.Лидеры.Вставить(КлючГруппы, Лидер);
Возврат;
КонецЕсли;
// Второй и последующие: выдаём себя за лидера, чтобы штатная идентификация
// (СначалаПоУникальномуИдентификаторуПотомПоПолямПоиска) нашла его документ.
ДанныеXDTO.КлючевыеСвойства.Ссылка = Лидер.Ссылка;
ДанныеXDTO.КлючевыеСвойства.Дата = Лидер.Дата;
ДанныеXDTO.КлючевыеСвойства.Номер = Лидер.Номер;
// Если в вашей версии Ссылка продублирована в корне структуры —
// раскомментировать (проверить на точке останова, см. комментарий в конце файла).
// Если ДанныеXDTO.Свойство("Ссылка") Тогда
// ДанныеXDTO.Ссылка = Лидер.Ссылка;
// КонецЕсли;
КонецПроцедуры
Функция КМ_ЭтоСворачиваемаяПередача(ДанныеXDTO)
Если Не ДанныеXDTO.Свойство("ВидОперации")
Или ДанныеXDTO.ВидОперации = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
Если ДанныеXDTO.ВидОперации.Значение <> "ПередачаНаКомиссию" Тогда
Возврат Ложь;
КонецЕсли;
Если Не ДанныеXDTO.Свойство("Контрагент")
Или ДанныеXDTO.Контрагент = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
ИНН = "";
ДанныеXDTO.Контрагент.Свойство("ИНН", ИНН);
Возврат СокрЛП(ИНН) = КМ_ИННКомиссионера();
КонецФункции
// Ключ группировки: день + договор. Организация и контрагент уже
// зафиксированы отбором выше.
Функция КМ_КлючГруппы(ДанныеXDTO)
Если Не ДанныеXDTO.КлючевыеСвойства.Свойство("Дата") Тогда
Возврат "";
КонецЕсли;
ИдентификаторДоговора = "";
Если ДанныеXDTO.Свойство("ДанныеВзаиморасчетов")
И ДанныеXDTO.ДанныеВзаиморасчетов <> Неопределено
И ДанныеXDTO.ДанныеВзаиморасчетов.Свойство("Договор")
И ДанныеXDTO.ДанныеВзаиморасчетов.Договор <> Неопределено Тогда
СсылкаДоговора = Неопределено;
ДанныеXDTO.ДанныеВзаиморасчетов.Договор.Свойство("Ссылка", СсылкаДоговора);
Если СсылкаДоговора <> Неопределено Тогда
ИдентификаторДоговора = Строка(СсылкаДоговора);
КонецЕсли;
КонецЕсли;
Возврат Формат(НачалоДня(ДанныеXDTO.КлючевыеСвойства.Дата), "ДФ=yyyyMMdd")
+ "|" + ИдентификаторДоговора;
КонецФункции
#КонецОбласти
#Область ОбъединениеТабличнойЧасти
Процедура КМ_ОбъединитьТовары(ДанныеИБ, КомпонентыОбмена)
Если ДанныеИБ = Неопределено Тогда
Возврат;
КонецЕсли;
Хранилище = КМ_Хранилище(КомпонентыОбмена);
Накопленные = Неопределено;
Хранилище.Свойство("НакопленныеТовары", Накопленные);
Если Накопленные = Неопределено Или Накопленные.Количество() = 0 Тогда
Возврат;
КонецЕсли;
// На этот момент типовой обработчик уже заместил ТЧ строками нового
// документа. Кладём обратно накопленные, следом дописываем новые.
НовыеСтроки = ДанныеИБ.Товары.Выгрузить();
ДанныеИБ.Товары.Загрузить(Накопленные);
Для Каждого СтрокаНовая Из НовыеСтроки Цикл
ЗаполнитьЗначенияСвойств(ДанныеИБ.Товары.Добавить(), СтрокаНовая);
КонецЦикла;
Хранилище.Вставить("НакопленныеТовары", Неопределено);
// Сумма шапки была перенесена из полученных данных и относится
// только к последнему документу — пересчитываем.
ДанныеИБ.СуммаДокумента = ДанныеИБ.Товары.Итог("Сумма");
КонецПроцедуры
#КонецОбласти
#Область Служебные
// Хранилище состояния на время одного сеанса обмена.
// ПараметрыКонвертации живут ровно столько, сколько нужно.
Функция КМ_Хранилище(КомпонентыОбмена)
ПараметрыКонвертации = КомпонентыОбмена.ПараметрыКонвертации;
Хранилище = Неопределено;
Если Не ПараметрыКонвертации.Свойство("КМ_СводныеПередачи", Хранилище)
Или Хранилище = Неопределено Тогда
Хранилище = Новый Структура;
Хранилище.Вставить("Лидеры", Новый Соответствие);
Хранилище.Вставить("НакопленныеТовары", Неопределено);
ПараметрыКонвертации.Вставить("КМ_СводныеПередачи", Хранилище);
КонецЕсли;
Возврат Хранилище;
КонецФункции
#КонецОбласти
////////////////////////////////////////////////////////////////////////////////
// ПЕРЕД ПЕРВЫМ ЗАПУСКОМ
//
// Поставить точку останова в КМ_ПодменитьКлючевыеСвойства и посмотреть
// фактическую структуру ДанныеXDTO. Проверить два места:
//
// 1. ДанныеXDTO.КлючевыеСвойства.Ссылка — что это: строка UID или
// структура со свойством "Значение". От этого зависит присваивание.
// 2. Есть ли Ссылка продублированной в корне ДанныеXDTO. Если да —
// раскомментировать соответствующий блок.
//
// Это единственное, что стоит уточнить в отладчике: остальное из типового
// кода читается однозначно.
////////////////////////////////////////////////////////////////////////////////