От наших любимых пользователей, которые работают с обработкой Диадок, поступает много предложений, как хороших, так и не очень. В один солнечный весенний день поступило письмо с предложением как-нибудь облегчить им работу и сделать функционал для удобного обмена документами. Т.к. они много пересылают в письмах друг другу информацию для обработки документов, а идентифицируют документы по номеру, дате, контрагенту и сумме платежа., то такой обмен данными не очень удобный т.к. на поиск документа у второго пользователя уходит много времени. Поэтому решили сделать обмен ссылками на документы. То есть дать пользователю возможность привычным образом через функционал «Получить ссылку» (Ctrl + F11) скопировать ссылку, переслать второму пользователю, а он по этой ссылке открыть документ.
Постановка задачи.
- Пользователь должен привычным способом получить ссылку на документ в виде текста (чтобы можно было отправить эту ссылку в мессенджере или по почте).
- Второй пользователь, который получает ссылку мог воспользоваться штатным функционалом «Перейти по ссылке» (Shift + F11), вставить ссылку и отрыть документ.
Пожелания: если обработка Диадок не открыта, то открыть обработку, а затем открыть документ из ссылки. Если обработка уже открыта, то сразу открыть документ по ссылке.
Вот так это выглядит итоговый результат:
Реализация.
Для получения строки со ссылкой на документ воспользуемся обработчиками формы ОбработкаПолученияСпискаНавигационныхСсылок и ОбработкаПолученияНавигационнойСсылки. Обработчики доступны, начиная с версии 8.3.19 (см. подробнее).
На форму ФормаПакетаУправляемая добавляем обработчики с кодом:
Формируем список навигационных ссылок, который покажем в системном диалоге. Будем формировать ссылку на документ ЭДО в 1С по уникальному идентификатору ссылки, а также сформируем ссылку на документ в веб версию Диадок.
&НаКлиенте
Процедура ОбработкаПолученияСпискаНавигационныхСсылок(СписокНавигационыхСсылок, КлючПоУмолчанию)
СписокНавигационыхСсылок.Очистить();
СписокНавигационыхСсылок.Добавить("ДокументЭДО", "Документ " + ТекущийДокумент.ИмяФайла);
СписокНавигационыхСсылок.Добавить("ДокументЭДОWeb", "Ссылка в Диадок " + ТекущийДокумент.ИмяФайла);Q95;
КонецПроцедуры
В обработчике ОбработкаПолученияНавигационнойСсылки сформируем значения навигационных ссылок:
&НаКлиенте
Процедура ОбработкаПолученияНавигационнойСсылки(Ключ, Представление, НавигационнаяСсылка, СтандартнаяОбработка)
Если Ключ = "ДокументЭДО" Тогда
НавигационнаяСсылка = ЭтотОбъект.ПолучитьНавигационнуюСсылкуОбработки()
+ СтрШаблон("?ДокументЭДО=%1", ТекущийДокумент.Идентификаторы.ДокументЭДО.УникальныйИдентификатор());
СтандартнаяОбработка = Ложь;
ИначеЕсли Ключ = "ДокументЭДОWeb" Тогда
НавигационнаяСсылка = МетодСервераБезКонтекста(Истина, "Модуль_Ядро().Документы_СсылкаВБраузере", ТекущийДокумент);
СтандартнаяОбработка = Ложь;
Иначе
Возврат;
КонецЕсли;
КонецПроцедуры
Половина задачи сделана. Теперь нужно реализовать функционал «Перейти по навигационной ссылке».
В модуль управляемого приложения добавляем обработчик ОбработкаПереходаПоНавигационнойСсылке.
В обработчике прописываем логику:
- Проверяем полученную ссылку на то, что она ссылается на обработку Диадок.
- Далее если среди открытых окон есть окно с обработкой Диадок, то формируем оповещение "Диадок_ОткрытьДокументЭДО" с параметрами из навигационной ссылки.
- Если окно с обработкой не открыто, то открываем форму обработки с параметрами формы из параметров навигационной ссылки.
Процедура ОбработкаПереходаПоНавигационнойСсылке(ДанныеПереходаПоНавигационнойСсылке, СтандартнаяОбработка)
Если СтрНайти(ДанныеПереходаПоНавигационнойСсылке.ОтносительнаяНавигационнаяСсылка,
"e1cib/app/Обработка.КонтурЭДО?") Тогда
структураПараметрыНавигационнойСсылки = Новый Структура();
Для Каждого КлючИЗначение Из ДанныеПереходаПоНавигационнойСсылке.ПараметрыНавигационнойСсылки Цикл
структураПараметрыНавигационнойСсылки.Вставить(КлючИЗначение.Ключ, КлючИЗначение.Значение);
КонецЦикла;
ОткрытыеОкна = ПолучитьОкна();
Для Каждого ОткрытоеОкно Из ОткрытыеОкна Цикл
Если СтрНайти(ОткрытоеОкно.Заголовок, "АРМ.Диадок") Тогда
СтандартнаяОбработка = Ложь;
// в новых версиях Диадок добавлена проверка на идентификатор окна
// поэтому нужно определить Источник
СодержимоеОкна = ОткрытоеОкно.Содержимое;
УИИсточник = ?(СодержимоеОкна.Количество(), СодержимоеОкна[0].УникальныйИдентификатор, Неопределено);
Оповестить("Диадок_ОткрытьДокументЭДО", структураПараметрыНавигационнойСсылки, УИИсточник);
Прервать;
КонецЕсли;
КонецЦикла;
// если окно не найдено, значит обработка не запущена
Если СтандартнаяОбработка Тогда
СтандартнаяОбработка = Ложь;
ПараметрыФормы = Новый Структура("ДокументЭДО", структураПараметрыНавигационнойСсылки);
ОткрытьФорму("Обработка.КонтурЭДО.Форма", ПараметрыФормы, , Новый УникальныйИдентификатор);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Теперь в ФормаУправляемая обработки Диадок необходимо добавить процедуру обработки оповещение и обработки параметров при открытии формы.
В обработчик ПриСозданииНаСервере добавил программное создание реквизита формы, в котором будут храниться данные по документу, который необходимо открыть. Если форма открывается из обработчика выше, то заполняем этот параметр из параметра формы:
НовыйРеквизит_СтрокаСписка = Новый РеквизитФормы("СтрокаСписка",
Новый ОписаниеТипов(), , "Строка списка при открытии по ссылке");
МассивНовыхРеквизитов.Добавить(НовыйРеквизит_СтрокаСписка);
СтрокаСписка = Неопределено;
Если Параметры.Свойство("ДокументЭДО", СтрокаСписка) Тогда
ЭтотОбъект["СтрокаСписка"] = СтрокаСписка;
КонецЕсли;
Дальше после выполнения авторизации на форме запускаются разные обработчики. В последний из запускаемых обработчиков ОжиданиеОплатыСервисаИОшибокМЧД подключил свой обработчик ожидания ОбработчикОткрытияДокументаЭДОПоСсылке:
&НаКлиенте
Процедура ОжиданиеОплатыСервисаИОшибокМЧД()
…
// подключаем обработчик перехода по ссылке документа ЭДО
ПодключитьОбработчикОжидания("ОбработчикОткрытияДокументаЭДОПоСсылке", 0.1, Истина);
КонецПроцедуры
Текст процедуры:
&НаКлиенте
Процедура ОбработчикОткрытияДокументаЭДОПоСсылке()
// параметр перезаписываем структурой документа, который нужно открыть
ЭтотОбъект["СтрокаСписка"] = ПолучитьСтрокуСпискаНаСервере(ЭтотОбъект["СтрокаСписка"]);
ОжиданиеОткрытияДокументовПоСсылке();
КонецПроцедуры
Функция ПолучитьСтрокуСпискаНаСервере возвращает структуру документа с такими же данными, как если бы мы открывали документ из списка документов формы Диадок:
&НаСервере
Функция ПолучитьСтрокуСпискаНаСервере(Параметр)
// при пустом значении параметра значит, что мы просто открываем форму
Если Не ЗначениеЗаполнено(Параметр) Тогда
Возврат Неопределено;
КонецЕсли;
// получаем документ ЭДО, который нужно открыть по уникальному идентификатору
ДокументЭДО = Справочники.Диадок_Документы.ПолучитьСсылку(
Новый УникальныйИдентификатор(Параметр.ДокументЭДО));
// формируем данные аналогично если бы открывали документ из списка
Ядро = Модуль_ЯдроНаСервере();
Результат = Ядро.Контракт_СтрокаСпискаДокументов();
ДанныеДокумента = Ядро.Документы_СохраненныйДокумент(ДокументЭДО);
ПараметрыПоиска = Ядро.Контракт_ПараметрыПолученияСпискаДокументов();
ОтборПоПакету = Новый Структура("BoxID, LetterID, DocumentID, ИдентификаторПакета");
ЗаполнитьЗначенияСвойств(ОтборПоПакету, ДанныеДокумента.Идентификаторы);
ОтборПоПакету.Вставить("ИдентификаторПакета", ОтборПоПакету.LetterId);
ПараметрыПоиска.Вставить("Режим",
?(ДанныеДокумента.Направление = "Входящее", "ПолученныеДокументы", "ОтправленныеДокументы"));
ПараметрыПоиска.Вставить("ПоказыватьЗавершенные", Истина);
ПараметрыПоиска.Вставить("ОтборПоПакету", ОтборПоПакету);
ПараметрыПоиска.Вставить("НачалоПериода", ДокументЭДО.ДатаЗагрузки - 1);
ПараметрыПоиска.Вставить("КонецПериода", ДокументЭДО.ДатаЗагрузки + 1);
ДанныеПолученныхДокументов = Ядро.СписокДокументов_Документы(ПараметрыПоиска);
СтрокаПоДокументу = ДанныеПолученныхДокументов.Найти(ДокументЭДО, "ДокументЭДО");
ЗаполнитьЗначенияСвойств(Результат, СтрокаПоДокументу);
Если ЗначениеЗаполнено(СтрокаПоДокументу.LetterId) Тогда
ИдентификаторПакета = СтрокаПоДокументу.LetterId;
ИначеЕсли ЗначениеЗаполнено(СтрокаПоДокументу.Документ) Тогда
ИдентификаторПакета = СтрокаПоДокументу.Документ.УникальныйИдентификатор();
Иначе
ИдентификаторПакета = Новый УникальныйИдентификатор;
КонецЕсли;
Результат.Ключ = ИдентификаторПакета;
Возврат Результат;
КонецФункции
В процедуре ОжиданиеОткрытияДокументовПоСсылке открываем форму пакета с документом если наш реквизит заполнен данными:
&НаКлиенте
Процедура ОжиданиеОткрытияДокументовПоСсылке()
Если ЗначениеЗаполнено(ЭтотОбъект["СтрокаСписка"]) Тогда
ОткрытьФормуПакета(ЭтотОбъект["СтрокаСписка"]);
КонецЕсли;
КонецПроцедуры
В процедуру ОбработкаОповещения добавил обработку своего оповещения, которое отрабатывает, когда форма обработки Диадок уже открыта и нужно только открыть пакет с документом:
&НаКлиенте
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
…
ИначеЕсли ИмяСобытия = "Диадок_ОткрытьДокументЭДО" Тогда
ЭтаФорма["СтрокаСписка"] = Параметр;
ОбработчикОткрытияДокументаЭДОПоСсылке();
КонецЕсли;
КонецПроцедуры
На этом всё. Получили желаемый результат на требование пользователей.