При переходе на новый формат электронных документов (УПД по приказу ФНС № 970) разработчики, интегрирующие 1С с системами ЭДО или настраивающие групповую выгрузку документов по приказу №970, часто сталкиваются со строгими правилами валидации XML-схем. Одной из распространенных проблем является ошибка отсутствия обязательных атрибутов в адресе участника сделки.
В этой статье мы подробно разберем ошибку The required attribute 'НаимСтран' is missing, возникающую при выполнении метода PostMessage, выясним, почему она появляется даже при визуально корректном XML, и рассмотрим способы её устранения.
Рассмотрим ситуацию: при попытке отправить исходящий УПД (формат 970) сервер оператора ЭДО возвращает ошибку валидации. Сообщение об ошибке выглядит следующим образом:
MessageToPost.DocumentAttachments[0]: { Location = Line: 30, Position: 5, /Файл[1]/Документ[1]/СвСчФакт[1]/ГрузПолуч[1]/Адрес[1]/АдрИнф[1]/@НаимСтран, Message = The required attribute 'НаимСтран' is missing. }
Ошибка прямо указывает на отсутствие атрибута НаимСтран (Наименование страны) в узле АдрИнф. Однако при отладке и просмотре сформированного XML, который возвращает метод генерации титула (например, GenerateTitleXml), мы можем видеть, что атрибут присутствует:
<АдрИнф КодСтр="643" НаимСтран="Россия" АдрТекст="Улица Пушкина дом Колотушкина" />
Возникает парадокс: визуально данные есть, но сервер их не принимает. Чаще всего такая проблема проявляется избирательно, например, при отправке документов на Индивидуальных предпринимателей (ИП), в то время как отправка на Юридических лиц (ООО, АО) проходит успешно.
Чтобы понять причину, обратимся к технической документации формата и XSD-схеме. В формате 970 требования к заполнению адресов стали строже по сравнению с предыдущими версиями.
Адрес в электронном документе может быть представлен в двух основных видах:
АдрТекст.Важное правило валидации: Если адрес передается как строка текста (заполнен атрибут АдрТекст), то наличие атрибута НаимСтран становится обязательным, даже если указан КодСтр="643". Валидатор проверяет пару: "Код страны" + "Наименование страны". Отсутствие любого из них при наличии текстового адреса приводит к фатальной ошибке.
Разберем основные причины, почему ошибка возникает на практике, особенно когда кажется, что все заполнено верно.
Это наиболее частая причина. В 1С мы часто используем готовые методы API (или COM-объекты) для генерации "черновика" XML. Метод GenerateTitleXml создает корректную структуру на основе переданных объектов.
Однако, после генерации, разработчики могут программно вмешиваться в полученный XML-строку или DOM-дерево перед отправкой (метод PostMessage). Например, чтобы "поправить" адрес для ИП, так как у них часто адрес регистрации записан одной строкой.
Если в коде происходит ручная сборка узла АдрИнф, и мы забываем явно прописать атрибут НаимСтран, валидация не пройдет.
// Пример ошибочной логики, которая может привести к проблеме
Если ЭтоИП Тогда
// Мы вручную формируем строку адреса, но забываем НаимСтран
СтрокаXML = СтрЗаменить(СтрокаXML, "СтарыйАдрес", "<АдрИнф КодСтр=""643"" АдрТекст=""" + АдресСтрокой + """ />");
КонецЕсли;
В этом примере атрибут НаимСтран="Россия" пропущен. Для формата 970 это критическая ошибка.
При заполнении объектов API Диадока (или другой системы ЭДО) для разных типов контрагентов используются разные структуры:
OrganizationDetails) адрес часто берется из структурированных данных (ЕГРЮЛ), что конвертируется в AddressRF.IndividualEntityDetails) адрес места жительства часто хранится в 1С как произвольная строка. При конвертации такой строки в объект API тип адреса становится ForeignAddress (или аналог с текстовым полем).Если мы передаем в API объект типа ForeignAddress (иностранный адрес), мы обязаны заполнить свойство Country (код) и текстовое описание. При сериализации в XML библиотека должна подставить и наименование страны. Если библиотека старая или параметры переданы неверно, атрибут может потеряться.
Давайте рассмотрим пошаговый алгоритм устранения ошибки.
Убедитесь, какой тип адреса вы используете для проблемного контрагента. Если это ИП и адрес записан строкой, необходимо использовать конструкцию, соответствующую типу АдрИнф (Адресная информация) с текстовым представлением.
При формировании данных для отправки (будь то заполнение COM-объекта или ручное формирование XML), всегда явно указывайте наименование страны, если используете текстовый адрес.
Пример правильного формирования узла (псевдокод):
// Правильная структура узла для текстового адреса
УзелАдреса = Новый Структура;
УзелАдреса.Вставить("КодСтр", "643");
УзелАдреса.Вставить("НаимСтран", "Россия"); // Обязательно!
УзелАдреса.Вставить("АдрТекст", "г. Москва, ул. Ленина, д. 1");
Если вы используете метод GenerateTitleXml, а ошибка все равно возникает, внимательно проверьте код, который выполняется между генерацией титула и отправкой (PostMessage).
Часто в интеграциях встречаются блоки кода вида:
ТитулXML = DiadocAPI.GenerateTitleXml(...);
// Блок "костылей" или исправлений
Если Контрагент.ЭтоИП Тогда
// Здесь происходит подмена адреса
// Проверьте, что в заменяемой строке есть НаимСтран="Россия"
КонецЕсли;
DiadocAPI.PostMessage(..., ТитулXML, ...);
Именно в блоке исправлений часто теряется атрибут.
Для диагностики выгрузите сформированный XML файл на диск перед отправкой. Для детального анализа структуры файла воспользуйтесь онлайн-валидатором XML от оператора ЭДО. Проверьте файл в личном кабинете сервиса (загрузив его как черновик). Это позволит увидеть реальную структуру файла, которая уходит на сервер, а не ту, которую вы "ожидаете" увидеть.
Ошибка The required attribute 'НаимСтран' is missing в формате УПД 970 при наличии АдрТекст является следствием строгого соблюдения XSD-схемы.
Для исправления необходимо:
КодСтр и НаимСтран.НаимСтран имеет значение "Россия" или "Российская Федерация".