gifts2017

История изменения контактной информации контрагентов, на примере cохранения истории изменений адресов партнеров и контрагентов, для УТ 11.2

Опубликовал Сергей Соловьев (sergey512) в раздел Программирование - Практика программирования

Сохраняем историю изменений адресов партнеров и контрагентов для УТ 11.2 с возможностью печати документов задним числом с нужными адресами. В публикации описаны необходимые минимальные доработки конфигурации для: хранения истории изменений и автоматической подстановки нужного адреса (в зависимости от даты) в печатные бланки.

Доработка тестировалась на конфигурации: Управление Торговлей 11.2 (11.2.3.129).

Задача: реализовать механиз хранения истории контактной информации для контрагентов и партнеров. 
Условие задачи: минимальные доработки типовой конфигурации. 

Реализация:

1) Создадим периодичесий "Регистре сведений", в котором будем хранить историю контактной информации.

- Наименование: ИсторияКонтактнойИнформации
- Синоним: История изменения контактной информации 
- Переодичность: В пределах секунды
- Режим записи : Независимый
- Измерения: Объект(СправочникСсылка.Контрагенты, СправочникСсылка.Партнеры), Тип, Вид, ВидДляСписка
- Ресурсы: Представление, ЗначенияПолей, Страна, Регион, Город, АдресЭП, ДоменноеИмяСервера, НомерТелефона, НомерТелефонаБезКодов

Измерения и ресурсы полностью взяты из табличной части "КонтактнаяИнформация" справочника "Контрагенты", кроме имерения "Объект". Данный регистр сведений позволит хранить историю любую контактной информации справочников "Партнеры" и "Контрагенты".
Не забываем на вкладке "права" настроить права для нужных ролей.

2) Создадим процедуру "СохранитьИсториюКонтактнойИнформации". Данную процедуру расположим в общем модуле "ПартнерыИКонтрагенты" и сделаем ее экспортной. В качестве параметра будем передавать объект, чью историю необходимо сохранить.

Процедура СохранитьИсториюКонтактнойИнформации(спрОбъект) Экспорт
    
    текДата = ТекущаяДатаСеанса();
    
    //Получаем уже сохраненную историю(на последнюю актуальную дату)...
    Запрос = Новый Запрос("ВЫБРАТЬ
                          |    История.Тип,
                          |    История.Вид,
                          |    История.ВидДляСписка,
                          |    История.Представление,
                          |    История.ЗначенияПолей,
                          |    История.Страна,
                          |    История.Регион,
                          |    История.Город,
                          |    История.АдресЭП,
                          |    История.ДоменноеИмяСервера,
                          |    История.НомерТелефона,
                          |    История.НомерТелефонаБезКодов
                          |ИЗ
                          |    РегистрСведений.ИсторияКонтактнойИнформации.СрезПоследних(&Дата, Объект = &Объект) КАК История");
    
    Запрос.УстановитьПараметр("Дата", текДата);
    Запрос.УстановитьПараметр("Объект", спрОбъект.Ссылка);
    
    РезультатЗапросаИстория = Запрос.Выполнить();
    табИстория = РезультатЗапросаИстория.Выгрузить();
    ПараметрыПоиска = Новый Структура;
    РеквизитыКонтактнойИнформации = спрОбъект.Метаданные().ТабличныеЧасти.КонтактнаяИнформация.Реквизиты;
    
    //Идем по контактной информации и сохраняем измененную и новую...
    Для каждого стрИнф из спрОбъект.КонтактнаяИнформация Цикл
        
        СохранятьКонтактнуюИнформацию = Ложь;
        
        //Если нет данных сохраняем сразу...
        Если РезультатЗапросаИстория.Пустой() Тогда
            СохранятьКонтактнуюИнформацию = Истина;
        Иначе
            
            ПараметрыПоиска.Очистить();
            ПараметрыПоиска.Вставить("Тип", стрИнф.Тип);
            ПараметрыПоиска.Вставить("Вид", стрИнф.Вид);
            ПараметрыПоиска.Вставить("ВидДляСписка", стрИнф.ВидДляСписка);
            
            //Ищем...
            масСтрок = табИстория.НайтиСтроки(ПараметрыПоиска);
            
            Если масСтрок.Количество() = 0 Тогда 
                СохранятьКонтактнуюИнформацию = Истина;

            Иначе
                
                //Сравним каждую колонку...
                Для каждого Рек из РеквизитыКонтактнойИнформации Цикл
                    Если масСтрок[0][Рек.имя] <> стрИнф[Рек.имя] Тогда
                        СохранятьКонтактнуюИнформацию = Истина;
                        Прервать;
                    КонецЕсли;    
                КонецЦикла;    
                
            КонецЕсли;    
            
        КонецЕсли;    
        
        //Сохраняем...
        Если СохранятьКонтактнуюИнформацию Тогда    
            
            НовКонИнф = РегистрыСведений.ИсторияКонтактнойИнформации.СоздатьМенеджерЗаписи();
            НовКонИнф.Объект = спрОбъект.Ссылка;
            НовКонИнф.Период = текДата;
        
            Для каждого Рек из РеквизитыКонтактнойИнформации Цикл
                НовКонИнф[Рек.имя] = стрИнф[Рек.имя];    
            КонецЦикла;    
        
            НовКонИнф.Записать();
            
        КонецЕсли;    
        
    КонецЦикла;
    
КонецПроцедуры 

   

3) В модуле объекта справочников "Партнеры" и "Контрагенты" в процедуре "ПередЗаписью" вызовем нашу процедуру "СохранитьИсториюКонтактнойИнформации". На данном этапе доработки история контактной информации уже будет сохраняться. 

4) В модуле менеджера нашего регистра сведений создадим экспортную функцию "ПолучитьПредставление". 

Функция ПолучитьПредставление(спрСсылка, Дата, Тип, Вид, ВидДляСписка = Неопределено) Экспорт
    
    Если ВидДляСписка = Неопределено Тогда
        ВидДляСписка = Справочники.ВидыКонтактнойИнформации.ПустаяСсылка();    
    КонецЕсли;    
    
    Запрос = Новый Запрос("ВЫБРАТЬ
                          |    История.Представление
                          |ИЗ
                          |    РегистрСведений.ИсторияКонтактнойИнформации.СрезПоследних(
                          |            &Дата,
                          |            Объект = &Объект
                          |                И Тип = &Тип
                          |                И Вид = &Вид
                          |                И ВидДляСписка = &ВидДляСписка) КАК История");
    
    Запрос.УстановитьПараметр("Дата", Дата);
    Запрос.УстановитьПараметр("Объект", спрСсылка);
    Запрос.УстановитьПараметр("Тип", Тип);
    Запрос.УстановитьПараметр("Вид", Вид);
    Запрос.УстановитьПараметр("ВидДляСписка", ВидДляСписка);
    
    ИсторияВыборка = Запрос.Выполнить().Выбрать();
    
    Если ИсторияВыборка.Следующий() Тогда 
        Возврат ИсторияВыборка.Представление;
   
    Иначе
        Возврат "";
    КонецЕсли;
    
КонецФункции

5) Для того, чтобы при печати адреса подставлялись из нашей сохраненной истории, вызовем функцию "ПолучитьПредставление" из модуля менеджера нашего регистра сведений. Место, откуда будем вызывать функцию, - это модуль "ФормированиеПечатныхФорм", в нем ищем функцию "ПолучитьАдресИзКонтактнойИнформации". Комментируем кусок кода и вызываем нашу функцию, как показано на скрине ниже.

6) В этом же модуле находим функцию "СведенияОЮрФизЛице" и добавляем параметр "ДатаПериода" в вызов функции "ПолучитьАдресИзКонтактнойИнформации".

7) Все готово.

Р.S. Не забываем перезаписать все справочники "Партнеры" и "Контрагенты", чтобы текущая контактная информация сохранилась в регистре сведений "ИсторияКонтактнойИнформации". 

Скачать файлы

Наименование Файл Версия Размер
ЗаполнитьИсториюТекущимиКонтактнымиДанными
.epf 7,02Kb
13.09.16
0
.epf 7,02Kb Скачать

См. также

Подписаться Добавить вознаграждение
Комментарии
1. Геннадий Жаркой (ifal) 15.09.16 08:40
А чем вам не подошел стандартный механизм версионирования?
2. Сергей Соловьев (sergey512) 15.09.16 12:56
(1) ifal, При использовании стандартного механизма версионирования, получим только историю изменения для просмотра. При печати документов задним числом, в печатный бланк будут подставляться текущие данные контактной информации, а не данные актуальные на дату документа. Т.е.перед печатью задним числом, придется менять все вручную. В способе описанном выше, адрес в печатный бланк подставится актуальный на дату документа. Аналогично адресу, можно подставлять и другие актуальные, на дату документа, данные из контактной информации.
3. Геннадий Жаркой (ifal) 15.09.16 13:42
(2) sergey512, Вы не поняли, что я спрашиваю. Я хочу узнать зачем делать новый регистр сведений, писать код, чтобы туда что-то сохранять, если есть подсистема версионирования, которая все это делает из коробки. Остается только достать оттуда данные и все. А в Платформе 8.3.9 можно будет через расширение решить вашу задачу, не снимая с поддержки конфигурацию, если опираться на версионирование.
4. Сергей Соловьев (sergey512) 15.09.16 14:07
(3) ifal, Согласен. Моя публикация - это всего лишь пример решения данной задачи. В ближайшее время напишу публикацию, по решению данной задачи с помощью механизма версионирования. Интересно будет сравнить быстродействие работы двух вариантов реализации.