Skip to content

Instantly share code, notes, and snippets.

@AskinNet
Forked from acharushkin/DiadocPlugin.bsl
Created May 18, 2023 08:34
Show Gist options
  • Save AskinNet/f8dd36c2cc3b799de840a99832ee84b8 to your computer and use it in GitHub Desktop.
Save AskinNet/f8dd36c2cc3b799de840a99832ee84b8 to your computer and use it in GitHub Desktop.
Добавить неформализованный документ в пакет УПД
#Область ПеременныеМодуля
Перем ОсновнойМодуль Экспорт;
#КонецОбласти
#Область ПрограммныйИнтерфейс
// Общая точка входа для кастомизации и переопределения поведения коробочной версии
//
// Параметры:
// ИмяСобытия - Строка - идентификатор события подключаемго модуля
// ПараметрыСобытия - Структура - параметры события ПМ
//
// Возвращаемое значение:
// Неопределено - в случае, если типовое поведение не меняется (обработка события ПМ отключена).
// Произвольный - любое значение, отличное от Неопределено, означает, что событие включено
//
Функция ОбработатьСобытие(ИмяСобытия, ПараметрыСобытия) Экспорт
Если ИмяСобытия = "ПодготовитьПакет" Тогда
Результат = ПодготовитьПакет(ПараметрыСобытия);
ИначеЕсли ИмяСобытия = "ПодготовитьЭлектронныйДокумент" Тогда
Результат = ПодготовитьЭлектронныйДокумент(ПараметрыСобытия);
ИначеЕсли ИмяСобытия = "ПолучитьТаблицуИспользуемыхВидовДокументов" Тогда
Результат = ПолучитьТаблицуИспользуемыхВидовДокументов(ПараметрыСобытия);
Иначе
Результат = Неопределено;
КонецЕсли;
Возврат Результат;
КонецФункции
#КонецОбласти
#Область СлужебныйПрограммныйИнтерфейс
#Область Диадок
Функция ЭДО_ВерсияAPIПодключаемогоМодуля() Экспорт
Возврат 4;
КонецФункции
#КонецОбласти
#Область СведенияОВнешнейОбработке
// Служебный метод для регистрации подключаемого модуля в справочнике "Дополнительные отчеты и обработки"
//
// Возвращаемое значение:
// Структура - см. ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке
//
Функция СведенияОВнешнейОбработке() Экспорт
ТаблицаКоманд = НоваяТаблицаКомандДополнительнойОбработки();
ДобавитьКоманду(
ТаблицаКоманд,
"Выполнение регламентных операций подключаемого модуля Диадок",
"ВыполнитьРегламентныеДействияПМ",
"ВызовСерверногоМетода"
);
ПараметрыРегистрации = Новый Структура;
ПараметрыРегистрации.Вставить("Вид", "ДополнительнаяОбработка");
ПараметрыРегистрации.Вставить("Наименование", "Контур.Диадок: Подключаемый модуль");
ПараметрыРегистрации.Вставить("БезопасныйРежим", Ложь);
ПараметрыРегистрации.Вставить("Версия", "0.1.0");
ПараметрыРегистрации.Вставить("Информация", "Подключаемый модуль для Контур.Диадок");
ПараметрыРегистрации.Вставить("Команды", ТаблицаКоманд);
Возврат ПараметрыРегистрации;
КонецФункции
// Служебный метод для регистрации подключаемого модуля в справочнике "Дополнительные отчеты и обработки"
//
// Параметры:
// ИдентификаторКоманды - Строка - идентификатор команды.
// ПараметрыВыполненияКоманды - Произвольный - параметры выполнения команды
//
Процедура ВыполнитьКоманду(ИдентификаторКоманды, ПараметрыВыполненияКоманды = Неопределено) Экспорт
Если ИдентификаторКоманды = "ВыполнитьРегламентныеДействияПМ" Тогда
ВыполнитьРегламентныеДействияПМ(ПараметрыВыполненияКоманды);
КонецЕсли;
КонецПроцедуры
#КонецОбласти
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
#Область ДополнительныеОтчетыИОбработки
Функция НоваяТаблицаКомандДополнительнойОбработки()
Команды = Новый ТаблицаЗначений;
Команды.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка"));
Команды.Колонки.Добавить("Идентификатор", Новый ОписаниеТипов("Строка"));
Команды.Колонки.Добавить("Использование", Новый ОписаниеТипов("Строка"));
Команды.Колонки.Добавить("Модификатор", Новый ОписаниеТипов("Строка"));
Команды.Колонки.Добавить("ПоказыватьОповещение", Новый ОписаниеТипов("Булево"));
Возврат Команды;
КонецФункции
Процедура ДобавитьКоманду(ТаблицаКоманд, Представление, Идентификатор, Использование, ПоказыватьОповещение = Ложь, Модификатор = "")
НоваяКоманда = ТаблицаКоманд.Добавить();
НоваяКоманда.Представление = Представление;
НоваяКоманда.Идентификатор = Идентификатор;
НоваяКоманда.Использование = Использование;
НоваяКоманда.ПоказыватьОповещение = ПоказыватьОповещение;
НоваяКоманда.Модификатор = Модификатор;
КонецПроцедуры
Процедура ВыполнитьРегламентныеДействияПМ(Параметры)
// Регламентные действия, НЕ требующие инициализации основного модуля
КонецПроцедуры
#КонецОбласти
#Область ОбработчикиСобытийПМ
// Описывает правила формирования состава пакета исходящих документов.
// https://developer.kontur.ru/Docs/Diadoc_UM/func/pm/Podgotovit%27Paket.html
//
// Параметры:
// ПараметрыСобытия - Структура - содержит ключи:
// * ВидПакетаРазвернутый - Структура - описание вида пакета
// * СтрокаСписка - Структура - значения колонок строки списка пакетов для отправки
// * Пакет - Структура - сведения о формируемом пакете
// * Результат_ИМ - Булево - (необязательный) Если ключа нет, значит это вызов перед типовым обработчиком
//
// Возвращаемое значение:
// Произвольный - Неопределено, если обработчик отключен, иначе Истина.
//
Функция ПодготовитьПакет(ПараметрыСобытия)
Если ОбработчикиСобытий_ЭтоВызовПередТиповымОбработчиком(ПараметрыСобытия) Тогда
Возврат Неопределено;
КонецЕсли;
ТекущийПакет = ПараметрыСобытия.Пакет;
Если ТекущийПакет.ИдентификаторВида = "ID_УПД" Тогда
СчетФактура = ТекущийПакет.ДокументУчета;
Договор = СчетФактура.ДоговорКонтрагента;
Пакеты_ДобавитьДоговор(ТекущийПакет, Договор);
ПрисоединенныеФайлы = ПрисоединенныеФайлыОбъекта(СчетФактура);
Для Каждого Приложение Из ПрисоединенныеФайлы Цикл
Пакеты_ДобавитьПриложение(ТекущийПакет, Приложение);
КонецЦикла;
Возврат Истина;
КонецЕсли;
КонецФункции
// Формирует контент электронного документа и заполняет сведения о нём (метаданные).
// https://developer.kontur.ru/Docs/Diadoc_UM/func/pm/Podgotovit%27ElektronnyyDokument.html
//
// Параметры:
// ПараметрыСобытия - Структура - содержит ключи:
// * Результат - Структура - описание электронного документа
// * ВидДокументаРазвернутый - Структура - описание вида документа
// * ДополнительныеПараметры - Структура, Неопределено - дополнительные параметры получения контента, которые
// могут быть определены в событии ПодготовитьДокумент при вызове
// метода ЭДО_ДокументМенеджер_ПодготовитьИДобавитьДокументВПакет
// * Результат_ИМ - Булево - (необязательный) Если ключа нет, значит это вызов перед типовым обработчиком
//
// Возвращаемое значение:
// Произвольный - Неопределено, если обработчик отключен, иначе Истина.
//
Функция ПодготовитьЭлектронныйДокумент(ПараметрыСобытия)
Если ОбработчикиСобытий_ЭтоВызовПередТиповымОбработчиком(ПараметрыСобытия) Тогда
Возврат Неопределено;
КонецЕсли;
ЭлектронныйДокумент = ПараметрыСобытия.Результат;
ВидДокумента = ПараметрыСобытия.ВидДокументаРазвернутый.ID;
ДопПараметры = ПараметрыСобытия.ДополнительныеПараметры;
Результат = Истина;
Если ВидДокумента = ВидДокументаДоговор() Тогда
Документы_ПодготовитьДоговор(ЭлектронныйДокумент);
ИначеЕсли ВидДокумента = ВидДокументаПриложение() Тогда
Документы_ПодготовитьПриложение(ЭлектронныйДокумент, ДопПараметры);
Иначе
Результат = Неопределено;
КонецЕсли;
Возврат Результат;
КонецФункции
// Определяет список видов электронных документов, их названия и форматы отправки.
// https://developer.kontur.ru/Docs/Diadoc_UM/func/pm/Poluchit%27TablitsuIspol%27zuyemykhVidovDokumentov.html
//
// Параметры:
// ПараметрыСобытия - Структура - содержит ключи:
// * Результат_ИМ - ТаблицаЗначений - (необязательный) таблица видов документов, сформированная типовым обработчиком.
// Если ключа нет, значит это вызов перед типовым обработчиком.
//
// Возвращаемое значение:
// ТаблицаЗначений - описания видов электронных документов.
// Неопределено - если обработчик отключен.
//
Функция ПолучитьТаблицуИспользуемыхВидовДокументов(ПараметрыСобытия)
Если ОбработчикиСобытий_ЭтоВызовПередТиповымОбработчиком(ПараметрыСобытия) Тогда
Возврат Неопределено;
КонецЕсли;
ВидыДокументов = ПараметрыСобытия.Результат_ИМ;
ВидыДокументов_ДобавитьНеформализованный(
ВидыДокументов,
ВидДокументаДоговор(),
"Договор"
);
ВидыДокументов_ДобавитьНеформализованный(
ВидыДокументов,
ВидДокументаПриложение(),
"Приложение"
);
Возврат ВидыДокументов;
КонецФункции
#КонецОбласти
#Область РаботаСВидамиДокументов
// Добавляет описание вида электронных документов
//
// Параметры:
// ВидыДокументов - ТаблицаЗначений - таблица видов электронных документов
// Идентификатор - Строка - идентификатор вида ЭД
// Представление - Строка - пользовательское представление вида ЭД
// ТипДокументаAPI - Строка - (Необязательный) тип электронного документа. По умолчанию "Nonformalized"
//
Процедура ВидыДокументов_ДобавитьНеформализованный(ВидыДокументов, Идентификатор, Представление, ТипДокументаAPI = "Nonformalized")
ТипКонтентаAPI = "";
ОсновнойМодуль.ЭДО_Служебные_ДобавитьСтрокуВТаблицуЗначений(
ВидыДокументов,
Идентификатор,
Представление,
ТипДокументаAPI,
ТипКонтентаAPI
);
КонецПроцедуры
// Идентификатор вида документа для договоров.
//
// Возвращаемое значение:
// Строка.
//
Функция ВидДокументаДоговор()
Возврат "ID_ДОГОВОР";
КонецФункции
// Идентификатор вида документа для приложений.
//
// Возвращаемое значение:
// Строка.
//
Функция ВидДокументаПриложение()
Возврат "ID_ПРИЛОЖЕНИЕ";
КонецФункции
#КонецОбласти
#Область РаботаСПакетамиДокументов
Процедура Пакеты_ДобавитьДоговор(Пакет, СсылкаНаДоговор)
ВидЭлектронногоДокумента = ВидДокументаДоговор();
УчетныйДокумент = СсылкаНаДоговор;
ОсновнойМодуль.ЭДО_ДокументМенеджер_ПодготовитьИДобавитьДокументВПакет(
Пакет,
УчетныйДокумент,
ВидЭлектронногоДокумента
);
КонецПроцедуры
Процедура Пакеты_ДобавитьПриложение(Пакет, ПрисоединенныйФайл)
ДанныеФайла = РаботаСФайлами.ДанныеФайла(ПрисоединенныйФайл);
ПараметрыОтправкиФайла = Новый Структура;
ПараметрыОтправкиФайла.Вставить("АдресФайла", ДанныеФайла.СсылкаНаДвоичныеДанныеФайла);
ПараметрыОтправкиФайла.Вставить("ИмяФайла", ДанныеФайла.ИмяФайла);
ВидЭлектронногоДокумента = ВидДокументаПриложение();
УчетныйДокумент = ДанныеФайла.Владелец;
ОсновнойМодуль.ЭДО_ДокументМенеджер_ПодготовитьИДобавитьДокументВПакет(
Пакет,
УчетныйДокумент,
ВидЭлектронногоДокумента,
ПараметрыОтправкиФайла
);
КонецПроцедуры
#КонецОбласти
#Область РаботаСЭлектроннымиДокументами
// Заполняет параметры для отправки договора.
//
// Параметры:
// ЭлектронныйДокумент - Структура - см. параметр "Результат" события "ПодготовитьЭлектронныйДокумент"
//
Процедура Документы_ПодготовитьДоговор(ЭлектронныйДокумент)
СсылкаНаДоговор = ЭлектронныйДокумент.Документ1С;
РеквизитыДокумента = РеквизитыДоговора(СсылкаНаДоговор);
ИмяФайла = ИмяФайлаДоговора(РеквизитыДокумента);
Файл = ФайлДоговораПоВнешнейПечатнойФорме(СсылкаНаДоговор);
Документы_ПодготовитьНеформализованныйДокумент(
ЭлектронныйДокумент,
Файл,
ИмяФайла,
РеквизитыДокумента
);
ЭлектронныйДокумент.ЗапрашиватьОтветнуюПодпись = Истина;
КонецПроцедуры
// Заполняет параметры отправки приложения.
//
// Параметры:
// ЭлектронныйДокумент - Структура - см. параметр "Результат" события "ПодготовитьЭлектронныйДокумент"
// ПараметрыОтправкиПриложения - Структура - см. параметр "ДополнительныеПараметры" события "ПодготовитьЭлектронныйДокумент"
//
Процедура Документы_ПодготовитьПриложение(ЭлектронныйДокумент, ПараметрыОтправкиПриложения)
РеквизитыДокумента = Неопределено;
ИмяФайла = ПараметрыОтправкиПриложения.ИмяФайла;
Файл = ПолучитьИзВременногоХранилища(ПараметрыОтправкиПриложения.АдресФайла);
Документы_ПодготовитьНеформализованныйДокумент(
ЭлектронныйДокумент,
Файл,
ИмяФайла,
РеквизитыДокумента
);
ЭлектронныйДокумент.ЗапрашиватьОтветнуюПодпись = Ложь;
КонецПроцедуры
// Заполняет параметры электронного неформализованного документа.
//
// Параметры:
// ЭлектронныйДокумент - Структура - см. параметр "Результат" события "ПодготовитьЭлектронныйДокумент"
// Файл - ДвоичныеДанные - содержимое электронного документа
// ИмяФайла - Строка - имя файла электронного документа
// РеквизитыДокумента - Структура - реквизиты учетного документа, на основании которого формируется электронный документ
//
Процедура Документы_ПодготовитьНеформализованныйДокумент(ЭлектронныйДокумент, Файл, ИмяФайла, РеквизитыДокумента)
ЭлектронныйДокумент.ИмяФайла = ИмяФайла;
ЭлектронныйДокумент.ДвоичныеДанные = Файл;
ЭлектронныйДокумент.Метаданные.FileName = ИмяФайла;
Если Не ЗначениеЗаполнено(РеквизитыДокумента) Тогда
Возврат;
КонецЕсли;
ЭлектронныйДокумент.Метаданные.DocumentDate = РеквизитыДокумента.Дата;
ЭлектронныйДокумент.Метаданные.DocumentNumber = РеквизитыДокумента.Номер;
Если ЭлектронныйДокумент.Метаданные.Свойство("TotalSum") Тогда
ЭлектронныйДокумент.Метаданные.TotalSum = РеквизитыДокумента.Сумма;
КонецЕсли;
Если ЭлектронныйДокумент.Метаданные.Свойство("TotalVat") Тогда
ЭлектронныйДокумент.Метаданные.TotalVat = РеквизитыДокумента.СуммаНДС;
КонецЕсли;
КонецПроцедуры
#КонецОбласти
#Область Прочие
// Получает ссылку на внешнюю печатную форму договора
//
// Возвращаемое значение:
// СправочникСсылка.ДополнительныеОтчетыИОбработки
//
Функция ВнешняяПечатнаяФормаДоговора()
НаименованиеВПФ = "Тестовая печатная форма";
Результат = Справочники.ДополнительныеОтчетыИОбработки.НайтиПоНаименованию(НаименованиеВПФ);
Возврат Результат;
КонецФункции
// Получает файл договора в формате PDF.
//
// Параметры:
// СсылкаНаДоговор - СправочникСсылка.ДоговорыКонтрагентов - ссылка на договор
//
// Возвращаемое значение:
// ДвоичныеДанные.
//
Функция ФайлДоговораПоВнешнейПечатнойФорме(СсылкаНаДоговор)
ВнешняяПечатнаяФорма = ВнешняяПечатнаяФормаДоговора();
КомандаПечати = "_ТестВнешняяПечатнаяФорма01";
Результат = СформироватьВнешнююПечатнуюФорму(СсылкаНаДоговор, ВнешняяПечатнаяФорма, КомандаПечати);
Возврат Результат;
КонецФункции
// Получает описание реквизитов договора
//
// Параметры:
// СсылкаНаДоговор - СправочникСсылка.ДоговорыКонтрагентов - ссылка на договор.
//
// Возвращаемое значение:
// Структура - см. НовыйРеквизитыУчетногоДокумента
//
Функция РеквизитыДоговора(СсылкаНаДоговор)
Результат = НовыйРеквизитыУчетногоДокумента();
Результат.Дата = СсылкаНаДоговор.Дата;
Результат.Номер = СсылкаНаДоговор.Номер;
Возврат Результат;
КонецФункции
// Формирует имя файла договора.
//
// Параметры:
// Реквизиты - Структура - см. НовыйРеквизитыУчетногоДокумента
//
// Возвращаемое значение:
// Строка.
//
Функция ИмяФайлаДоговора(Реквизиты, РасширениеФайла = "pdf")
ЧастиИмени = Новый Массив;
ЧастиИмени.Добавить("Договор №");
ЧастиИмени.Добавить(Реквизиты.Номер);
ЧастиИмени.Добавить(" от ");
ЧастиИмени.Добавить(Формат(Реквизиты.Дата, "ДФ=dd.MM.yyyy"));
Если ЗначениеЗаполнено(РасширениеФайла) Тогда
ЧастиИмени.Добавить(".");
ЧастиИмени.Добавить(РасширениеФайла);
КонецЕсли;
Результат = СтрСоединить(ЧастиИмени);
Возврат Результат;
КонецФункции
// Получает файл печатной формы объекта в формате PDF.
//
// Параметры:
// СсылкаНаОбъект - ЛюбаяСсылка - ссылка на объект печати.
// ДополнительнаяОбработкаСсылка - СправочникСсылка.ДополнительныеОтчетыИОбработки - внешняя печатная форма.
// ИдентификаторКомандыПечатнойФормы - Строка - идентификатор команды печати.
//
// Возвращаемое значение:
// ДвоичныеДанные - файл в формате PDF.
//
Функция СформироватьВнешнююПечатнуюФорму(СсылкаНаОбъект, ДополнительнаяОбработкаСсылка, ИдентификаторКомандыПечатнойФормы)
КоллекцияПечатныхФорм = Неопределено;
ПараметрыВывода = Неопределено;
ОбъектыНазначения = Новый Массив;
ОбъектыНазначения.Добавить(СсылкаНаОбъект);
ПараметрыИсточника = Новый Структура("ИдентификаторКоманды, ОбъектыНазначения", ИдентификаторКомандыПечатнойФормы, ОбъектыНазначения);
ОбъектыПечати = Новый СписокЗначений;
ДополнительныеОтчетыИОбработки.ПечатьПоВнешнемуИсточнику(
ДополнительнаяОбработкаСсылка,
ПараметрыИсточника,
КоллекцияПечатныхФорм,
ОбъектыПечати,
ПараметрыВывода
);
Если ТипЗнч(КоллекцияПечатныхФорм) <> Тип("ТаблицаЗначений") ИЛИ КоллекцияПечатныхФорм.Количество() <> 1 Тогда
ВызватьИсключение "Не удалось сформировать печатную форму """ + ДополнительнаяОбработкаСсылка + """ для документа " + СсылкаНаОбъект;
КонецЕсли;
ПечатнаяФорма = КоллекцияПечатныхФорм[0];
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("pdf");
ПечатнаяФорма.ТабличныйДокумент.Записать(ИмяВременногоФайла, ТипФайлаТабличногоДокумента.PDF);
Результат = Новый ДвоичныеДанные(ИмяВременногоФайла);
УдалитьФайлы(ИмяВременногоФайла);
Возврат Результат;
КонецФункции
// Получает список присоединенных файлов объекта.
//
// Параметры:
// ВладелецФайлов - ЛюбаяСсылка - владелец присоединенных файлов.
//
// Возвращаемое значение:
// Массив из ПрисоединенныйФайл.
//
Функция ПрисоединенныеФайлыОбъекта(ВладелецФайлов)
ТекстЗапроса =
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
| ТаблицаПрисоединенныеФайлы.Ссылка КАК Ссылка,
| ТаблицаПрисоединенныеФайлы.Наименование КАК Наименование
|ИЗ
| &ПолноеИмяТаблицы КАК ТаблицаПрисоединенныеФайлы
|ГДЕ
| ТаблицаПрисоединенныеФайлы.ВладелецФайла = &ВладелецФайлов
| И НЕ ТаблицаПрисоединенныеФайлы.ПометкаУдаления
|
|УПОРЯДОЧИТЬ ПО
| Наименование";
МетаданныеОбъекта = ВладелецФайлов.Метаданные();
ПолноеИмяТаблицыХраненияФайлов = "Справочник." + МетаданныеОбъекта.Имя + "ПрисоединенныеФайлы";
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ПолноеИмяТаблицы", ПолноеИмяТаблицыХраненияФайлов);
Результат = Новый Массив;
Запрос = Новый Запрос(ТекстЗапроса);
Запрос.УстановитьПараметр("ВладелецФайлов", ВладелецФайлов);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Результат.Добавить(Выборка.Ссылка);
КонецЦикла;
Возврат Результат;
КонецФункции
// Конструктор описания реквивизитов учетного документа
//
// Возвращаемое значение:
// Структура.
//
Функция НовыйРеквизитыУчетногоДокумента()
Результат = Новый Структура;
Результат.Вставить("Дата", Дата(1, 1, 1));
Результат.Вставить("Номер", "");
Результат.Вставить("Сумма", 0);
Результат.Вставить("СуммаНДС", 0);
Возврат Результат;
КонецФункции
Функция ОбработчикиСобытий_ЭтоВызовПослеТиповогоОбработчика(ПараметрыСобытия)
Результат = Ложь;
Если ТипЗнч(ПараметрыСобытия) = Тип("Структура") Тогда
Результат = ПараметрыСобытия.Свойство("Результат_ИМ");
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ОбработчикиСобытий_ЭтоВызовПередТиповымОбработчиком(ПараметрыСобытия)
Результат = Не ОбработчикиСобытий_ЭтоВызовПослеТиповогоОбработчика(ПараметрыСобытия);
Возврат Результат;
КонецФункции
#КонецОбласти
#КонецОбласти
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment