Всем доброго времени суток.
Столкнулся с вопросом использовать функционал факсимиле в БП 3.0 (3.0.77.106) и вот незадача как оказалось использовать можно только подпись ответственных лиц организации, а как быть с сотрудниками с правом подписи? тем более что их можно указывать в документах в поле руководитель или ответственный??
На ИТС есть описание, что такой механизм есть, но в моем релизе почему-то он отсутствует, и пришлось немного покопаться и поискать его в базе.
Но почему-то не нашел такого функционала в базе, хотя подбор изображения подписи указанного руководителя присутствует, но сама подпись способна быть присвоена только у организации во всем известном пункте.
Есть замечательный общий модуль: «УправлениеПечатьюБП» и в ней есть функция для формирования соответствия Факсимиле ( ПолучитьДанныеФаксимиле), но вот незадача в нее не попадает документ, только карточка организации и получить из ее тела документ или указанных в нем физических лиц не представляется возможным, хотя при выводе изображений на печатные формы в универсальном механизме происходит попытка получения подписи из переменной «СоответствиеФаксимиле», другое дело что попасть ей туда неоткуда и негде.
Как не искал, так и не нашел где привязать изображение к физлицу и ничего лучше не придумал как использовать справочник «Файлы», тем более, что он прекрасно работает с изображениями и есть к нему даже целый общий модуль «РаботаСФайлами», нам с него понадобится только одна функция: «РаботаСФайлами.ДанныеФайла(СсылкаНаСправочникФайлы)».
Как решение предлагаю добавить явный реквизит, в котором хранить ссылку на «файл» с хранящемся факсимиле, и по его заполненности использовать для печатных форм.
Но для такого решения у пользователя должны быть права на работу со справочником «Файлы».
В модуле «УправлениеПечатьюБП» есть интересное место где можем выполнить недостающее требование, и загрузить изображения, подписи использованных в документе физ. лиц, процедура «ДополнитьДокументПодписьюИПечатью» где мы и можем получить ситуацию одновременно присутствия самого документа, и заполненной переменной «СоответствиеФаксимиле». Которую тут же можно дополнить.
&НаСервере
Функция ПолучитьСсылкуНаВременноеХранилищеИзображенияИзВложенногоФайла(ОбъектВладелецФайла,ИмяПоляПрисоединенногоФайла)
ПрисоединенныйФайл = ОбъектВладелецФайла[ИмяПоляПрисоединенногоФайла];
Если ЗначениеЗаполнено(ПрисоединенныйФайл) Тогда
ДанныеКартинки = РаботаСФайлами.ДанныеФайла(ПрисоединенныйФайл);
ДвоичныеДанныеКартинки = ПолучитьИзВременногоХранилища(ДанныеКартинки.СсылкаНаДвоичныеДанныеФайла);
КонецЕсли;
СсылкаНаВременноеХранилище = ПоместитьВоВременноеХранилище(Новый Картинка(ДвоичныеДанныеКартинки), Новый УникальныйИдентификатор);
Возврат СсылкаНаВременноеХранилище;
КонецФункции
&ИзменениеИКонтроль("ДополнитьДокументПодписьюИПечатью")
Процедура ТРМедия_ДополнитьДокументПодписьюИПечатью(ОбластьМакета, СведенияОДокументе, ОбъектыПечати, ПараметрыПечати)
КлючевыеДанные = Новый Структура("Документ, Организация,
|Предприниматель, Руководитель, ГлавныйБухгалтер,
|ОтветственныйЗаОформление, Исполнитель, Кладовщик");
// Заполняем по данным печатной формы
Если ТипЗнч(СведенияОДокументе) = Тип("ВыборкаИзРезультатаЗапроса") Тогда
ЗаполнитьЗначенияСвойств(КлючевыеДанные, СведенияОДокументе);
Колонки = СведенияОДокументе.Владелец().Колонки;
ИначеЕсли ТипЗнч(СведенияОДокументе) = Тип("СтрокаТаблицыЗначений") Тогда
Колонки = СведенияОДокументе.Владелец().Колонки;
Если Колонки.Найти("ДанныеШапки") <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(КлючевыеДанные, СведенияОДокументе.ДанныеШапки);
Иначе
ЗаполнитьЗначенияСвойств(КлючевыеДанные, СведенияОДокументе);
КонецЕсли;
Иначе
УдалитьВсеОбластиФаксимиле(ОбластьМакета);
Возврат;
КонецЕсли;
// Если не нашлось одноименных полей, ищем похожие
Если НЕ ЗначениеЗаполнено(КлючевыеДанные.Документ) Тогда
Если Колонки.Найти("Ссылка") <> Неопределено Тогда
КлючевыеДанные.Документ = СведенияОДокументе.Ссылка;
Иначе
УдалитьВсеОбластиФаксимиле(ОбластьМакета);
Возврат;
КонецЕсли;
КонецЕсли;
ИсключаемыеТипыДокументов = ИсключаемыеТипыДокументов(ПараметрыПечати);
Если ИсключаемыеТипыДокументов.Найти(ТипЗнч(КлючевыеДанные.Документ)) <> Неопределено Тогда
ДанныеОбласти = ОбъектыПечати.НайтиПоЗначению(КлючевыеДанные.Документ);
ОбластьВладелец = ДанныеОбласти.Представление;
МассивИменПоказателей = МассивИменПоказателейФаксимиле();
Для Каждого ЗначениеПоказателя ИЗ МассивИменПоказателей Цикл
ОчиститьОбластьФаксимиле(ОбластьМакета, ЗначениеПоказателя);
КонецЦикла;
Возврат;
Иначе
// Организация не всегда хранится в реквизите Организация
Если НЕ ЗначениеЗаполнено(КлючевыеДанные.Организация) И Колонки.Найти("Поставщик") <> Неопределено Тогда
КлючевыеДанные.Организация = СведенияОДокументе.Поставщик;
КонецЕсли;
Если НЕ ЗначениеЗаполнено(КлючевыеДанные.Организация) И Колонки.Найти("Грузоотправитель") <> Неопределено Тогда
КлючевыеДанные.Организация = СведенияОДокументе.Грузоотправитель;
КонецЕсли;
Если НЕ ЗначениеЗаполнено(КлючевыеДанные.Организация) И Колонки.Найти("ДанныеШапки") <> Неопределено Тогда
Если НЕ ЗначениеЗаполнено(КлючевыеДанные.Организация) И СведенияОДокументе.ДанныеШапки.Свойство("Поставщик") <> Неопределено Тогда
КлючевыеДанные.Организация = СведенияОДокументе.ДанныеШапки.Поставщик;
КонецЕсли;
Если НЕ ЗначениеЗаполнено(КлючевыеДанные.Организация) И СведенияОДокументе.ДанныеШапки.Свойство("Грузоотправитель") <> Неопределено Тогда
КлючевыеДанные.Организация = СведенияОДокументе.ДанныеШапки.Грузоотправитель;
КонецЕсли;
КонецЕсли;
Если НЕ ЗначениеЗаполнено(КлючевыеДанные.Организация)
ИЛИ ТипЗнч(КлючевыеДанные.Организация) <> Тип("СправочникСсылка.Организации") Тогда
УдалитьВсеОбластиФаксимиле(ОбластьМакета);
Возврат;
КонецЕсли;
// Ситуация, когда в документе подписанты явно не указаны
Если НЕ ЗначениеЗаполнено(КлючевыеДанные.Руководитель)
ИЛИ НЕ ЗначениеЗаполнено(КлючевыеДанные.ГлавныйБухгалтер) Тогда
ДатаДокумета = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(КлючевыеДанные.Документ, "Дата");
Руководители = ОтветственныеЛицаБП.ОтветственныеЛица(КлючевыеДанные.Организация, ДатаДокумета);
Если НЕ ЗначениеЗаполнено(КлючевыеДанные.Руководитель) Тогда
КлючевыеДанные.Руководитель = Руководители.Руководитель;
КонецЕсли;
Если НЕ ЗначениеЗаполнено(КлючевыеДанные.ГлавныйБухгалтер) Тогда
КлючевыеДанные.ГлавныйБухгалтер = Руководители.ГлавныйБухгалтер;
КонецЕсли;
КонецЕсли;
Если НЕ ЗначениеЗаполнено(КлючевыеДанные.Исполнитель) Тогда
Если Колонки.Найти("ПредставительОрганизации") <> Неопределено Тогда
КлючевыеДанные.Исполнитель = СведенияОДокументе.ПредставительОрганизации;
Иначе
КлючевыеДанные.Исполнитель = КлючевыеДанные.Руководитель;
КонецЕсли;
КонецЕсли;
Если НЕ ЗначениеЗаполнено(КлючевыеДанные.Кладовщик) Тогда
Если Колонки.Найти("ОтпускПроизвел") <> Неопределено Тогда
КлючевыеДанные.Кладовщик = СведенияОДокументе.ОтпускПроизвел;
Иначе
Если ЗначениеЗаполнено(КлючевыеДанные.Исполнитель) Тогда
КлючевыеДанные.Кладовщик = КлючевыеДанные.Исполнитель;
ИначеЕсли ЗначениеЗаполнено(КлючевыеДанные.Руководитель) Тогда
КлючевыеДанные.Кладовщик = КлючевыеДанные.Руководитель;
КонецЕсли;
КонецЕсли;
КонецЕсли;
// Предприниматель - он же руководитель
Если НЕ ЗначениеЗаполнено(КлючевыеДанные.Предприниматель) Тогда
КлючевыеДанные.Предприниматель = КлючевыеДанные.Руководитель;
КонецЕсли;
КонецЕсли;
ДанныеОбласти = ОбъектыПечати.НайтиПоЗначению(КлючевыеДанные.Документ);
ОбластьВладелец = ДанныеОбласти.Представление;
ПозицияРазделителя = СтрНайти(ОбластьВладелец, ";", НаправлениеПоиска.СКонца);
Если ПозицияРазделителя <> 0 Тогда
ОбластьВладелец = СокрЛП(Прав(ОбластьВладелец, СтрДлина(ОбластьВладелец) - ПозицияРазделителя));
ДанныеОбласти.Представление = ОбластьВладелец;
КонецЕсли;
СоответствиеФаксимиле = Новый Соответствие;
МассивИменПоказателей = Новый Массив;
МассивУдаляемыхИменПоказателей = Новый Массив;
ОрганизацияЮридическоеЛицо = Истина;
ПолучитьДанныеФаксимиле(СоответствиеФаксимиле,
МассивИменПоказателей,
МассивУдаляемыхИменПоказателей,
ОрганизацияЮридическоеЛицо,
КлючевыеДанные.Организация,
ПараметрыПечати);
#Вставка
СсылкаНаВременноеХранилище = Неопределено;
Если ЗначениеЗаполнено(КлючевыеДанные.Руководитель) Тогда
Если ЗначениеЗаполнено(КлючевыеДанные.Руководитель.TRMedia_ФайлПодписьФизЛица) Тогда
СсылкаНаВременноеХранилище = ПолучитьСсылкуНаВременноеХранилищеИзображенияИзВложенногоФайла(КлючевыеДанные.Руководитель,"TRMedia_ФайлПодписьФизЛица");
СоответствиеФаксимиле.Вставить(КлючевыеДанные.Руководитель,
СсылкаНаВременноеХранилище);
КонецЕсли;
КонецЕсли;
#КонецВставки
// Удаляем заведомо лишние картинки из табличного документа
Для Каждого ЗначениеПоказателя ИЗ МассивУдаляемыхИменПоказателей Цикл
ОчиститьОбластьФаксимиле(ОбластьМакета, ЗначениеПоказателя);
КонецЦикла;
// В некоторых случаях на форме есть взаимоисключающие реквизиты.
// Например, подпись руководителя и подпись предпринимателя в счете-фактуре
Если ОрганизацияЮридическоеЛицо Тогда
ОчиститьОбластьФаксимиле(ОбластьМакета, "ФаксимилеПредприниматель");
Иначе
ОбластьФаксимиле = ОбластьМакета.Области.Найти("ФаксимилеПредприниматель");
Если ОбластьФаксимиле <> Неопределено Тогда
ОчиститьОбластьФаксимиле(ОбластьМакета, "ФаксимилеРуководитель");
КонецЕсли;
КонецЕсли;
РасшифровкаФаксимилеМакета = Новый Структура();
Для Каждого ЗначениеПоказателя ИЗ МассивИменПоказателей Цикл
// Печать нельзя привязать к ответственному лицу
Если СтрНайти(ЗначениеПоказателя, "ФаксимилеПечать") > 0
ИЛИ СтрНайти(ЗначениеПоказателя, "ФаксимильнаяПечать") > 0 Тогда
КлючСоответствия = "Организация";
Иначе
КлючСоответствия = СтрЗаменить(ЗначениеПоказателя, "Факсимиле", "");
КлючСоответствия = СтрЗаменить(КлючСоответствия, "Накладная", "");
КлючСоответствия = СтрЗаменить(КлючСоответствия, "Услуги", "");
КлючСоответствия = СтрЗаменить(КлючСоответствия, "Материалы", "");
КонецЕсли;
ОбработатьОбластьФаксимиле(РасшифровкаФаксимилеМакета,
ОбластьВладелец,
ОбластьМакета,
ЗначениеПоказателя,
КлючевыеДанные,
КлючСоответствия,
СоответствиеФаксимиле);
КонецЦикла;
// Измененный макет, не содержащий области факсимиле
Если РасшифровкаФаксимилеМакета.Количество() = 0 Тогда
УдалитьВсеОбластиФаксимиле(ОбластьМакета);
Возврат;
КонецЕсли;
// Расшифровка в первой колонке последней строки
АдресПараметровРасшифровки = ПоместитьВоВременноеХранилище(РасшифровкаФаксимилеМакета, Новый УникальныйИдентификатор);
ОбластьРасшифровки = ОбластьМакета.Область("R" + Формат(ОбластьМакета.Области[ОбластьВладелец].Низ, "ЧГ=")
+ "C1:R" + Формат(ОбластьМакета.Области[ОбластьВладелец].Низ, "ЧГ=") + "C1");
ОбластьРасшифровки.Имя = "РасшифровкаФаксимилеМакета_" + ОбластьВладелец;
ОбластьРасшифровки.Расшифровка = АдресПараметровРасшифровки;
ОбластьРасшифровки.ИспользованиеРасшифровки = ИспользованиеРасшифровкиТабличногоДокумента.БезОбработки;
КонецПроцедуры
&ИзменениеИКонтроль("НастройкиПодписиИПечати")
Функция ТРМедия_НастройкиПодписиИПечати(ИмяМакета)
Настройки = Новый Структура;
Настройки.Вставить("ВыводитьФаксимиле", Ложь);
Настройки.Вставить("ФаксимилеДоступноДляВывода", Истина);
НастройкиВыводаФаксимиле = ХранилищеОбщихНастроек.Загрузить("УправлениеФаксимиле", "НастройкиВыводаФаксимиле");
Если НастройкиВыводаФаксимиле <> Неопределено
И НастройкиВыводаФаксимиле.Свойство("ФаксимилеДоступноДляВывода") Тогда
Настройки.ФаксимилеДоступноДляВывода = НастройкиВыводаФаксимиле.ФаксимилеДоступноДляВывода;
Если Не Настройки.ФаксимилеДоступноДляВывода Тогда
Возврат Настройки;
КонецЕсли;
ВыводитьФаксимиле = Неопределено;
НастройкиВыводаФаксимиле.Свойство("ВыводитьФаксимиле" + ИмяМакета, ВыводитьФаксимиле);
Если ВыводитьФаксимиле <> Неопределено Тогда
#Удаление
Настройки.ВыводитьФаксимиле = ВыводитьФаксимиле;
#КонецУдаления
#Вставка
Настройки.ВыводитьФаксимиле = ?(НастройкиВыводаФаксимиле.ФаксимилеДоступноДляВывода,Истина,ВыводитьФаксимиле);
#КонецВставки
КонецЕсли;
КонецЕсли;
Возврат Настройки;
КонецФункции
Как-то так. Надеюсь, кому-нибудь поможет.
Тестировалось на Бухгалтерия предприятия, редакция 3.0 (3.0.77.106) .