Доработка тестировалась на конфигурации: Управление Торговлей 11.2 (11.2.3.129).
Задача: реализовать механиз хранения истории контактной информации для контрагентов и партнеров.
Условие задачи: минимальные доработки типовой конфигурации.
Реализация:
1) Создадим периодический "Регистр сведений", в котором будем хранить историю контактной информации.
- Наименование: ИсторияКонтактнойИнформации
- Синоним: История изменения контактной информации
- Переодичность: В пределах секунды
- Режим записи : Независимый
- Измерения: Объект(СправочникСсылка.Контрагенты, СправочникСсылка.Партнеры), Тип, Вид, ВидДляСписка
- Ресурсы: Представление, ЗначенияПолей, Страна, Регион, Город, АдресЭП, ДоменноеИмяСервера, НомерТелефона, НомерТелефонаБезКодов
Измерения и ресурсы полностью взяты из табличной части "КонтактнаяИнформация" справочника "Контрагенты", кроме имерения "Объект". Данный регистр сведений позволит хранить историю любую контактной информации справочников "Партнеры" и "Контрагенты".
Не забываем на вкладке "права" настроить права для нужных ролей.
2) Создадим процедуру "СохранитьИсториюКонтактнойИнформации". Данную процедуру расположим в общем модуле "ПартнерыИКонтрагенты" и сделаем ее экспортной. В качестве параметра будем передавать объект, чью историю необходимо сохранить.
Процедура СохранитьИсториюКонтактнойИнформации(спрОбъект) Экспорт
текДата = ТекущаяДатаСеанса();
//Получаем уже сохраненную историю(на последнюю актуальную дату)...
Запрос = Новый Запрос("ВЫБРАТЬ
| История.Тип,
| История.Вид,
| История.ВидДляСписка,
| История.Представление,
| История.ЗначенияПолей,
| История.Страна,
| История.Регион,
| История.Город,
| История.АдресЭП,
| История.ДоменноеИмяСервера,
| История.НомерТелефона,
| История.НомерТелефонаБезКодов
|ИЗ
| РегистрСведений.ИсторияКонтактнойИнформации.СрезПоследних(&Дата, Объект = &Объект) КАК История");
Запрос.УстановитьПараметр("Дата", текДата);
Запрос.УстановитьПараметр("Объект", спрОбъект.Ссылка);
РезультатЗапросаИстория = Запрос.Выполнить();
табИстория = РезультатЗапросаИстория.Выгрузить();
ПараметрыПоиска = Новый Структура;
РеквизитыКонтактнойИнформации = спрОбъект.Метаданные().ТабличныеЧасти.КонтактнаяИнформация.Реквизиты;
//Идем по контактной информации и сохраняем измененную и новую...
Для каждого стрИнф из спрОбъект.КонтактнаяИнформация Цикл
СохранятьКонтактнуюИнформацию = Ложь;
//Если нет данных сохраняем сразу...
Если РезультатЗапросаИстория.Пустой() Тогда
СохранятьКонтактнуюИнформацию = Истина;
Иначе
ПараметрыПоиска.Очистить();
ПараметрыПоиска.Вставить("Тип", стрИнф.Тип);
ПараметрыПоиска.Вставить("Вид", стрИнф.Вид);
ПараметрыПоиска.Вставить("ВидДляСписка", стрИнф.ВидДляСписка);
//Ищем...
масСтрок = табИстория.НайтиСтроки(ПараметрыПоиска);
Если масСтрок.Количество() = 0 Тогда
СохранятьКонтактнуюИнформацию = Истина;
Иначе
//Сравним каждую колонку...
Для каждого Рек из РеквизитыКонтактнойИнформации Цикл
Если масСтрок[0][Рек.имя] <> стрИнф[Рек.имя] Тогда
СохранятьКонтактнуюИнформацию = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
//Сохраняем...
Если СохранятьКонтактнуюИнформацию Тогда
НовКонИнф = РегистрыСведений.ИсторияКонтактнойИнформации.СоздатьМенеджерЗаписи();
НовКонИнф.Объект = спрОбъект.Ссылка;
НовКонИнф.Период = текДата;
Для каждого Рек из РеквизитыКонтактнойИнформации Цикл
НовКонИнф[Рек.имя] = стрИнф[Рек.имя];
КонецЦикла;
НовКонИнф.Записать();
КонецЕсли;
КонецЦикла;
КонецПроцедуры
3) В модуле объекта справочников "Партнеры" и "Контрагенты" в процедуре "ПередЗаписью" вызовем нашу процедуру "СохранитьИсториюКонтактнойИнформации". На данном этапе доработки история контактной информации уже будет сохраняться.
4) В модуле менеджера нашего регистра сведений создадим экспортную функцию "ПолучитьПредставление".
Функция ПолучитьПредставление(спрСсылка, Дата, Тип, Вид, ВидДляСписка = Неопределено) Экспорт
Если ВидДляСписка = Неопределено Тогда
ВидДляСписка = Справочники.ВидыКонтактнойИнформации.ПустаяСсылка();
КонецЕсли;
Запрос = Новый Запрос("ВЫБРАТЬ
| История.Представление
|ИЗ
| РегистрСведений.ИсторияКонтактнойИнформации.СрезПоследних(
| &Дата,
| Объект = &Объект
| И Тип = &Тип
| И Вид = &Вид
| И ВидДляСписка = &ВидДляСписка) КАК История");
Запрос.УстановитьПараметр("Дата", Дата);
Запрос.УстановитьПараметр("Объект", спрСсылка);
Запрос.УстановитьПараметр("Тип", Тип);
Запрос.УстановитьПараметр("Вид", Вид);
Запрос.УстановитьПараметр("ВидДляСписка", ВидДляСписка);
ИсторияВыборка = Запрос.Выполнить().Выбрать();
Если ИсторияВыборка.Следующий() Тогда
Возврат ИсторияВыборка.Представление;
Иначе
Возврат "";
КонецЕсли;
КонецФункции
5) Для того, чтобы при печати адреса подставлялись из нашей сохраненной истории, вызовем функцию "ПолучитьПредставление" из модуля менеджера нашего регистра сведений. Место, откуда будем вызывать функцию, - это модуль "ФормированиеПечатныхФорм", в нем ищем функцию "ПолучитьАдресИзКонтактнойИнформации". Комментируем кусок кода и вызываем нашу функцию, как показано на скрине ниже.
6) В этом же модуле находим функцию "СведенияОЮрФизЛице" и добавляем параметр "ДатаПериода" в вызов функции "ПолучитьАдресИзКонтактнойИнформации".
7) Все готово.
Р.S. Не забываем перезаписать все справочники "Партнеры" и "Контрагенты", чтобы текущая контактная информация сохранилась в регистре сведений "ИсторияКонтактнойИнформации".