При файловом обмене электронными УПД иногда возникает занятная ситуация: в самой 1С все ответственные лица заполнены, печатная форма УПД выглядит правильно, но после команды «ЭДО → Выгрузить документ в файл» в XML получаем:
<Подписант ТипПодпис="2" СпосПодтПолном="1">
<ФИО Фамилия="-" Имя="-"/>
</Подписант>
Далее такой файл загружается, подписывается уже отдельно в другом сервисе и отправляется покупателю. В результате покупатель получает УПД без заполненных сведений о подписанте.
В нашем случае дополнительно был конкретный контрагент, который особенно капризничал по этому поводу, поэтому менять поведение всех исходящих документов не требовалось. Нужно было заполнить подписанта только для одного контрагента по ИНН.
Пример выполнен для:
1С:Бухгалтерия предприятия, редакция 3.0, релиз 3.0.201.16.
Почему стандартная настройка подписей организации не помогает
Сначала кажется логичным проверить:
- руководителя организации;
- главного бухгалтера;
- ответственного за оформление УПД;
- сотрудника и его должность.
Это действительно нужно для печатной формы и других реквизитов УПД. Но с элементом XML <Подписант> история отдельная.
В типовом модуле ФорматыЭДО_ФНС при первоначальном формировании УПД 5.03 подписант создается специально с пустыми значениями:
РаботаСФайламиБЭД.ЗаполнитьСвойствоXDTO(
Подписант, "Должн", "-", Истина, Ошибки);
РаботаСФайламиБЭД.ЗаполнитьСвойствоXDTO(
Подписант, "ТипПодпис", "2", Истина, Ошибки);
РаботаСФайламиБЭД.ЗаполнитьСвойствоXDTO(
Подписант, "СпосПодтПолном", "1", Истина, Ошибки);
ФИО = ПолучитьОбъектТипаCML("ФИОТип", ПространствоИмен);
РаботаСФайламиБЭД.ЗаполнитьСвойствоXDTO(
ФИО, "Фамилия", "-", , Ошибки);
РаботаСФайламиБЭД.ЗаполнитьСвойствоXDTO(
ФИО, "Имя", "-", , Ошибки);
То есть прочерки появляются не из-за неправильно заполненного справочника. Их ставит сама типовая конфигурация.
Дальше штатный механизм 1С предполагает отдельный этап заполнения данных подписанта при использовании сертификата ЭП. В модуле ФорматыЭДО для этого существует функция ЗаполнитьДанныеПодписантаДокумента(), где ФИО и должность уже получаются из параметров сертификата.
Но если используется схема:
1С
Выгрузить документ в файл
Подписание и отправка
этот второй этап в 1С просто не выполняется.
Получаем маленькую архитектурную щель, через которую и просачивается наш Фамилия="-".
Что будем делать
Основную конфигурацию менять не будем. Делаем небольшое расширение и вмешиваемся уже после штатного формирования XML.
Подход удобен тем, что типовая 1С сначала полностью создает УПД, а мы меняем только три реквизита:
Фамилия
Имя / Отчество
Должность
ТипПодпис и СпосПодтПолном оставляем такими, какими их сформировала сама 1С.
Удобная точка находится в общем модуле ФорматыЭДО, функция:
СформироватьДанныеОсновногоТитулаПоОбъектуУчета()
В ней одновременно доступны исходный документ, выбранный формат и уже сформированный XML.
Создание расширения
- Открываем Конфигуратор → Конфигурация → Расширения конфигурации и создаем расширение, например
РПП_ПодписантУПД. Назначение можно установить «Исправление». - Добавляем в расширение существующий общий модуль основной конфигурации
ФорматыЭДО. - В расширении перехватываем
СформироватьДанныеОсновногоТитулаПоОбъектуУчета()через&Вместо, но первым делом вызываемПродолжитьВызов(). Таким образом штатный код продолжает работать полностью. - После формирования проверяем тип документа, формат УПД 5.03 и ИНН контрагента.
- Только если все условия совпали, открываем сформированный XDTO и заменяем пустого подписанта.
Код расширения
В нашем примере специальная обработка нужна для контрагента с отбором по ИНН.
Руководитель уже заполнен в самой реализации. Для нашего случая должность подписанта: «Генеральный директор».
&Вместо("СформироватьДанныеОсновногоТитулаПоОбъектуУчета")
Функция РПП_СформироватьДанныеОсновногоТитулаПоОбъектуУчета(
ОбъектУчета,
Настройки,
Данные) Экспорт
// Сначала выполняем весь штатный механизм 1С.
Результат = ПродолжитьВызов(
ОбъектУчета,
Настройки,
Данные);
Если Результат = Неопределено
Или Результат.ЕстьОшибки Тогда
Возврат Результат;
КонецЕсли;
// Только документы реализации.
Если ТипЗнч(ОбъектУчета)
<> Тип("ДокументСсылка.РеализацияТоваровУслуг") Тогда
Возврат Результат;
КонецЕсли;
// Только УПД 5.03, информация продавца.
Форматы = ФорматыЭДО.ПоддерживаемыеФорматы();
Если Настройки.Формат
<> Форматы.ФНС.УПД_5_03.ИнформацияПродавца Тогда
Возврат Результат;
КонецЕсли;
// Проверяем конкретного контрагента.
ИННКонтрагента = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(
ОбъектУчета.Контрагент,
"ИНН");
Если ИННКонтрагента <> "НАШ ИНН КОНТРАГЕНТА" Тогда
Возврат Результат;
КонецЕсли;
Если Результат.Документ = Неопределено
Или Результат.Документ.ДвоичныеДанные = Неопределено Тогда
Возврат Результат;
КонецЕсли;
РПП_ЗаполнитьПодписантаУПД(
Результат,
ОбъектУчета);
Возврат Результат;
КонецФункции
Процедура РПП_ЗаполнитьПодписантаУПД(
Результат,
ОбъектУчета)
// Основной источник подписанта.
ФизическоеЛицо = ОбъектУчета.Руководитель;
// Если руководитель почему-то не указан,
// пробуем ответственного за оформление УПД.
Если Не ЗначениеЗаполнено(ФизическоеЛицо) Тогда
ФизическоеЛицо = ОбъектУчета.ОтветственныйЗаОформление;
КонецЕсли;
Если Не ЗначениеЗаполнено(ФизическоеЛицо) Тогда
Возврат;
КонецЕсли;
// В конкретной базе представление физлица имеет вид
// "Фамилия Имя Отчество".
ЧастиФИО = СтрРазделить(
СокрЛП(Строка(ФизическоеЛицо)),
" ");
Если ЧастиФИО.Количество() < 2 Тогда
Возврат;
КонецЕсли;
Фамилия = ЧастиФИО[0];
Имя = ЧастиФИО[1];
Отчество = "";
Если ЧастиФИО.Количество() >= 3 Тогда
Отчество = ЧастиФИО[2];
КонецЕсли;
ОписаниеОшибки = "";
ДанныеФайлаЭД = ФорматыЭДО.ДанныеФайлаЭД(
Результат.Документ,
ОписаниеОшибки);
Если Не ПустаяСтрока(ОписаниеОшибки)
Или ДанныеФайлаЭД = Неопределено Тогда
Возврат;
КонецЕсли;
Если ДанныеФайлаЭД.Документ = Неопределено
Или ДанныеФайлаЭД.Документ.Подписант.Количество() = 0 Тогда
Возврат;
КонецЕсли;
// Типовой УПД уже содержит пустого подписанта.
ИндексПодписанта =
ДанныеФайлаЭД.Документ.Подписант.Количество() - 1;
Подписант =
ДанныеФайлаЭД.Документ.Подписант[ИндексПодписанта];
ФИО = РаботаСФайламиБЭД.ЗначениеСвойстваXDTO(
Подписант,
"ФИО");
Если ФИО = Неопределено Тогда
Возврат;
КонецЕсли;
Ошибки = Неопределено;
РаботаСФайламиБЭД.ЗаполнитьСвойствоXDTO(
ФИО,
"Фамилия",
Фамилия,
Истина,
Ошибки);
РаботаСФайламиБЭД.ЗаполнитьСвойствоXDTO(
ФИО,
"Имя",
Имя,
Истина,
Ошибки);
Если Не ПустаяСтрока(Отчество) Тогда
РаботаСФайламиБЭД.ЗаполнитьСвойствоXDTO(
ФИО,
"Отчество",
Отчество,
,
Ошибки);
КонецЕсли;
РаботаСФайламиБЭД.ЗаполнитьСвойствоXDTO(
Подписант,
"ФИО",
ФИО,
Истина,
Ошибки);
// В нашем случае подписантом является генеральный директор.
РаботаСФайламиБЭД.ЗаполнитьСвойствоXDTO(
Подписант,
"Должн",
"Генеральный директор",
Истина,
Ошибки);
Если ЗначениеЗаполнено(Ошибки) Тогда
Возврат;
КонецЕсли;
// Собираем XDTO обратно в XML.
ПространствоИмен =
ДанныеФайлаЭД.Тип().URIПространстваИмен;
ДвоичныеДанные =
РаботаСФайламиБЭД.XDTOВДвоичныеДанные(
ДанныеФайлаЭД,
Ложь,
,
"Файл");
Результат.Документ.ДвоичныеДанные =
ОбщегоНазначенияБЭД.УдалитьПространствоИмен(
ДвоичныеДанные,
ПространствоИмен);
// После изменения XML обновляем разобранное содержание документа.
Результат.Содержание =
ФорматыЭДО.ПрочитатьСодержаниеДокумента(
Результат.Документ);
КонецПроцедуры
Сам ДанныеФайлаЭД() является экспортной функцией типового модуля, поэтому нам не приходится вручную разбирать XML строковыми заменами.
Что получится
До установки расширения:
<Подписант ТипПодпис="2" СпосПодтПолном="1">
<ФИО Фамилия="-" Имя="-"/>
</Подписант>
После:
<Подписант
Должн="Генеральный директор"
ТипПодпис="2"
СпосПодтПолном="1">
<ФИО
Фамилия="Иванов"
Имя="Иван"
Отчество="Иванович"/>
</Подписант>
При этом ТипПодпис="2" и СпосПодтПолном="1" мы специально не меняем. Задача расширения не заключается в имитации электронной подписи. Мы только заполняем учетные сведения о лице, которое должно отображаться подписантом.
Для любого другого покупателя код закончится здесь:
Если ИННКонтрагента <> "НАШ ИНН КОНТРАГЕНТА" Тогда
Возврат Результат;
КонецЕсли;
и XML останется полностью типовым.
Проверка
После подключения расширения нужно заново открыть реализацию и выполнить «ЭДО → Выгрузить документ в файл».
Старые ранее выгруженные XML, естественно, сами не изменятся.
Я бы проверил два документа: первый на проблемного контрагента, где в <Подписант> должны появиться ФИО и должность, второй на любого другого покупателя, где расширение вообще не должно вмешиваться.
В итоге получаем очень локальную доработку: не меняем основную конфигурацию, не переписываем механизм формирования УПД и не затрагиваем остальных контрагентов. Один капризный покупатель получает нужный ему XML, а остальной ЭДО продолжает жить своей типовой жизнью.
Вступайте в нашу телеграмм-группу Инфостарт