Permalink
Branch: master
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
287 lines (185 sloc) 23.1 KB

Как подготовить пакет документов для отправки

Модуль «Диадок Про» умеет отправлять документы контрагентам. По одной сделке часто требуется отправить не один документ, а минимум два.

Поэтому документы объединяются в :doc:`Пакет <../../objects/Paket>`. Состоять такой пакета может из нескольких доступных :doc:`типов документов <../../objects/Tipy_Dokumentov>`.

Аналогично веб-версии, одновременно нельзя отправить больше 30 документов.

Предварительно следует пакет назвать, определить состав и логику сбора документов. Каждый этап подготовки описывается в событии подключаемого модуля.

Названия пакетов

Документы, которые будут отправлены вместе, отображаются в списке для отправки в одну строку.

Стоит назвать каждую группу, чтобы пользователю понимать состав пакета. Например, согласно бизнес-логике («Возмещение») или типу документа («УПД»).

Наименование пакета, которое будет отображаться в интерфейсе, определяется в функции :doc:`ПолучитьТаблицуИспользуемыхПакетов <../../func/pm/Poluchit'TablitsuIspol'zuyemykhPaketov>`.

Пример определения пакетов "УПД" и "Возмещение":

ТЗ  = Новый ТаблицаЗначений;
ОсновнойМодуль.ЭДО_Служебные_ДобавитьКолонкиВТаблицуЗначений(ТЗ, "ID, Наименование, УПД");

ОсновнойМодуль.ЭДО_Служебные_ДобавитьСтрокуВТаблицуЗначений(ТЗ, "ID_УПД",         "УПД",  Истина);
ОсновнойМодуль.ЭДО_Служебные_ДобавитьСтрокуВТаблицуЗначений(ТЗ, "ID_Возмещение",  "Возмещение");

Форматы документов

При формировании документа важно знать какие сведения документа передавать, учитывать ограничения, накладываемые ФНС, и т.п.

Для объединения похожих по структуре документов используются такие характеристики: :doc:`тип контента <../../objects/Tipy_Kontenta>`, функция и :doc:`тип документа <../../objects/Tipy_Dokumentov>` API.

Определение комбинаций этих характеристик ("видов документов"), которые будут использованы в пакетах на отправку, происходит в функции :doc:`ПолучитьТаблицуИспользуемыхВидовДокументов <../../func/pm/Poluchit'TablitsuIspol'zuyemykhVidovDokumentov>`

Пример определения УПД и Счета на оплату:

ТЗ  = Новый ТаблицаЗначений;
ОсновнойМодуль.ЭДО_Служебные_ДобавитьКолонкиВТаблицуЗначений(ТЗ, "ID, Наименование, ТипДокументаAPI, ТипКонтентаAPI, ФункцияДокументаAPI");

ОсновнойМодуль.ЭДО_Служебные_ДобавитьСтрокуВТаблицуЗначений(ТЗ, "ID_УПД",   "УПД",  "UniversalTransferDocument",  "utd", "СЧФДОП");
ОсновнойМодуль.ЭДО_Служебные_ДобавитьСтрокуВТаблицуЗначений(ТЗ, "ID_Счет",  "Счет", "ProformaInvoice",            "");

Заполнение списка пакетов на отправку

Построение запроса для заполнения списка пакетов на отправку происходит в функции :doc:`ПолучитьТекстЗапросаДляСпискаПакетовНаОтправкуПоМассивуВидовПакетов <../../func/pm/Poluchit'TekstZaprosaDlyaSpiskaPaketovNaOtpravkuPoMassivuVidovPaketov>`.

Логика заполнения пакета предусматривает наличие одного главного документа, без которого отправлять контрагенту остальные не имеет смыла.

Сколько таких документов будет выбрано в запросе, столько пакетов и будет сформировано на отправку.

Пример выбора счетов-фактур из 1С для формирования вида пакета «УПД»:

Если ВидПакетаРазвернутый.ID = "ID_УПД" Тогда

    Результат = ДобавитьОбъединениеВТекстЗапроса(Результат) +

    "ВЫБРАТЬ
    | СчетФактураВыданный.Ссылка КАК Документ,
    | СчетФактураВыданный.Номер КАК НомерДокумента,
    | СчетФактураВыданный.Дата КАК ДатаДокумента,
    | СчетФактураВыданный.Контрагент КАК Контрагент,
    | СчетФактураВыданный.Организация КАК Организация,
    | СчетФактураВыданный.СуммаДокумента КАК СуммаДокумента,
    | ""ID_УПД"" КАК ВидПакетаID
    |ИЗ
    | Документ.СчетФактураВыданный КАК СчетФактураВыданный
    |     ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_КэшКонтрагентовПоВидамУПД КАК ВТ_КэшКонтрагентовПоВидамУПД
    |     ПО СчетФактураВыданный.Организация = ВТ_КэшКонтрагентовПоВидамУПД.Организация1С
    |         И СчетФактураВыданный.Контрагент = ВТ_КэшКонтрагентовПоВидамУПД.Контрагент1С
    |     ЛЕВОЕ СОЕДИНЕНИЕ Документ.ПакетЭД.ЭлектронныеДокументы КАК ОтправленныеДокументы
    |     ПО ТипЗначения(ОтправленныеДокументы.ОбъектВладелец) = Тип(Документ.СчетФактураВыданный)
    |         И СчетФактураВыданный.Ссылка = ОтправленныеДокументы.ОбъектВладелец
    |         И (ОтправленныеДокументы.Ссылка.ВнешнийУИД = ""ID_УПД"")
    |ГДЕ
    | ОтправленныеДокументы.Ссылка ЕСТЬ NULL
    | И СчетФактураВыданный.Дата МЕЖДУ &НачалоПериода И &КонецПериода
    | И СчетФактураВыданный.Проведен
    | И СчетФактураВыданный.ВидСчетаФактуры = ЗНАЧЕНИЕ(Перечисление.ВидСчетаФактурыВыставленного.НаРеализацию)
    | И СчетФактураВыданный.ДоговорКонтрагента.ВидДоговора = ЗНАЧЕНИЕ(Перечисление.ВидыДоговоровКонтрагентов.СПокупателем)
    | И НЕ СчетФактураВыданный.Исправление
    | И ВТ_КэшКонтрагентовПоВидамУПД.ИспользоватьУПД_МеткаОсновногоПакета";

КонецЕсли;

Состав пакетов

Наполнение документами происходит в функции :doc:`ПодготовитьПакет <../../func/pm/Podgotovit'Paket>`.

Для каждого вида пакета вычисляются ссылки на документы 1С, которые стоит подготовить и добавить в электронном виде.

Это может быть только главный документ, либо связанные с ним документы и т.п.

Добавление документа в пакет происходит с помощью метода основного модуля "ЭДО_ДокументМенеджер_ПодготовитьИДобавитьДокументВПакет".

В качестве параметров передаются:

  • ссылка на пакет, в который добавляется документ
  • ссылка на документ 1С, по сведениям которого будет сформирован электронный документ
  • внутренний идентификатор вида документов, в формате которого будет сформирован электронный документ
  • дополнительный параметр, который будет передан в функцию по формированию электронного документа (необязательный)

Пользователю видны подготовленные документы в форме пакета на отправку.

Пример определения состава пакетов вида "УПД" (формируется из одного документа Счет-фактуры) и "Возмещение" (зависит от реквизитов списка):

Если ВидПакетаРазвернутый.ID = "ID_УПД" Тогда

    ОсновнойМодуль.ЭДО_ДокументМенеджер_ПодготовитьИДобавитьДокументВПакет(Пакет, СтрокаСписка.Документ, "ID_УПД");

ИначеЕсли ВидПакетаРазвернутый.ID = "ID_Возмещение" Тогда

    ОсновнойМодуль.ЭДО_ДокументМенеджер_ПодготовитьИДобавитьДокументВПакет(Пакет, СтрокаСписка.Документ, "ID_ОтчетИсполнителя");
    ОсновнойМодуль.ЭДО_ДокументМенеджер_ПодготовитьИДобавитьДокументВПакет(Пакет, СтрокаСписка.ДопРеквизит1, "ID_Счет");
    Если ЗначениеЗаполнено(СтрокаСписка.ДопРеквизит2) Тогда
        ОсновнойМодуль.ЭДО_ДокументМенеджер_ПодготовитьИДобавитьДокументВПакет(Пакет, СтрокаСписка.ДопРеквизит2, "ID_СчетФактураВозмещение");
    КонецЕсли;

КонецЕсли;

Формирование электронного документа

Электронный документ состоит из метаданных и контента, заполнение которых происходит в функции :doc:`ПодготовитьЭлектронныйДокумент <../../func/pm/Podgotovit'ElektronnyyDokument>`.

Описание требуется для каждого вида документа или типа контента, которые используются при отправке.

Формализованный

Сбор контента для формализованных документов проще всего сделать с помощью метода основного модуля "ТиповойМодуль_ПолучитьКонтент".

В параметрах передается ссылка на документ 1С и тип контента, который надо собрать. Если это УПД или УКД, то в дополнительных параметрах стоит указать функцию.

Полученную структуру переводим в объект XDTO с помощью метода основного модуля "ЗаполнитьКонтентXDTOПоСтруктуре".

Пример типового сбора контента для документов типа "УПД":

Результат = Параметры.Результат;
ВидДокументаРазвернутый = Параметры.ВидДокументаРазвернутый;
ДополнительныеПараметры = Параметры.ДополнительныеПараметры;

Документ1С               = Результат.Документ1С;
ВидДокументаНаименование = ВидДокументаРазвернутый.Наименование;

ID               = ВидДокументаРазвернутый.ID;
ТипКонтента_XDTO = ВидДокументаРазвернутый.ТипКонтента;
TypeNamedId      = ВидДокументаРазвернутый.TypeNamedId;
FormatVersion    = ВидДокументаРазвернутый.FormatVersion;
FunctionName     = ВидДокументаРазвернутый.FunctionName;

Если ВРЕГ(ТипКонтента_XDTO) = ВРЕГ("UtdSellerContent") ИЛИ ВРЕГ(ТипКонтента_XDTO) = ВРЕГ("UcdSellerContent") Тогда

    //Получим функцию документа, которая используется в типовом модуле
    Если TypeNamedId = "Invoice" ИЛИ TypeNamedId = "InvoiceRevision" Тогда
      ФункцияУПД = "СЧФ";
    ИначеЕсли TypeNamedId = "XmlTorg12" ИЛИ TypeNamedId = "XmlAcceptanceCertificate" Тогда
      ФункцияУПД = "ДОП";
    Иначе
      ФункцияУПД = ОсновнойМодуль.ФункцияДокументаДляXML(TypeNamedId, FunctionName);
    КонецЕсли;

    Если ЗначениеЗаполнено(ФункцияУПД) Тогда
        ДополнительныеПараметры = Новый Структура("ПараметрыСогласования, ДопСведения, ФИОПодписанта, ФункцияУПД", Неопределено, Неопределено, " ", ФункцияУПД);
        Content = ОсновнойМодуль.ТиповойМодуль_ПолучитьКонтент(ТиповойМодульДиадока(), РежимУправляемыхФорм, Документ1С, ТипКонтента_XDTO, ДополнительныеПараметры);
        ОсновнойМодуль.ЗаполнитьКонтентXDTOПоСтруктуре(Результат.Content, Content);
    КонецЕсли;

КонецЕсли;

Если документ 1С доработан, или сбор контента для его типа не определен в модуле, тогда можно воспользоваться шаблоном кода.

В настройке модуля на закладке "Подключаемый модуль" при нажатии на кнопку "Генерировать пример подключаемого модуля" откроется вспомогательная форма.

В этой форме надо отметить галочкой нужный формат документа и нажать "Сгенерировать шаблон кода ПМ".

Определение значений полей формата есть в документации.

Пример заполнения UtdSellerContent:

...........

Результат = Параметры.Результат;

Если ВРЕГ(ТипКонтента_XDTO) = ВРЕГ("UtdSellerContent") Тогда

    Если ТипЗнч(Основание) = Тип("ДокументСсылка.АР_НачислениеАренднойПлаты") Тогда
        Заполнить_UtdSellerContent(Результат.Content, Документ1С, ФункцияУПД);
    КонецЕсли;

КонецЕсли;

.......

Процедура Заполнить_UtdSellerContent(Контент, Параметры, ФункцияУПД)

    УстановитьЗначениеXDTO(Контент, "Function",               ФункцияУПД);
    УстановитьЗначениеXDTO(Контент, "Date",                   Параметры.Дата);
    УстановитьЗначениеXDTO(Контент, "Number",                 ПрефиксацияОбъектовКлиентСервер.ПолучитьНомерНаПечать(Параметры.Номер, Истина, Ложь));
    УстановитьЗначениеXDTO(Контент, "Currency",               Параметры.ВалютаДокумента.Код);
    УстановитьЗначениеXDTO(Контент, "Creator",                Параметры.Организация.Наименование);
    УстановитьЗначениеXDTO(Контент, "GovernmentContractInfo", ?(ФункцияУПД = "ДОП", Неопределено, Параметры.ИдентификаторГосКонтракта));
    УстановитьЗначениеXDTO(Контент, "ВалютаСсылка",           Параметры.ВалютаДокумента, Истина);

    Заполнить_ExtendedOrganizationInfo (Контент.Seller, Параметры.Организация);
    Заполнить_ExtendedOrganizationInfo (Контент.Buyer, Параметры.Контрагент);
    Заполнить_InvoiceTable             (Контент.InvoiceTable, Параметры, ФункцияУПД);
    Заполнить_AdditionalInfoId         (Контент.AdditionalInfoId, Неопределено);
    Заполнить_TransferInfo             (Контент.TransferInfo, Параметры);

КонецПроцедуры

Не формализованные документы

Для не формализованных документов заполняется мета и файл.

Мета содержит сведения о номере, дате документа, имени файла и т.д. в зависимости от типа документа.

Получить двоичные данные файла можно несколькими способами:

  • с помощью метода основного модуля "ТиповойМодуль_СформироватьПечатнуюФорму" для типовых печатных форм документов "Счет на оплату" и "Акта сверки"
Если ID = "ID_Счет" Тогда

    ДополнительныеПараметры = Новый Структура("ПараметрыСогласования, ФИОПодписанта", Неопределено, " ");
    ДанныеПечатнойФормы = ОсновнойМодуль.ТиповойМодуль_СформироватьПечатнуюФорму(ТиповойМодульДиадока(), РежимУправляемыхФорм, Документ1С, "СчетНаОплату", ДополнительныеПараметры);

    Результат.Метаданные.DocumentDate   = Документ1С.Дата;
    Результат.Метаданные.DocumentNumber = СокрЛП(Документ1С.Номер);
    Результат.Метаданные.FileName       = ДанныеПечатнойФормы.ИмяФайла;

    Если TypeNamedId = "ProformaInvoice" Тогда
      Результат.Метаданные.TotalSum = Документ1С.СуммаДокумента;
    ИначеЕсли TypeNamedId = "Nonformalized" Тогда
      //Результат.ЗапрашиватьОтветнуюПодпись = Истина;
    КонецЕсли;

    Результат.ДвоичныеДанные = Новый ДвоичныеДанные(ДанныеПечатнойФормы.ИмяВременногоФайла);

    УдалитьФайлы(ДанныеПечатнойФормы.ИмяВременногоФайла);

КонецЕсли;
  • с помощью метода "СформироватьВнешнююПечатнуюФорму" для внешних печатных форм
Если ID = "ID_ИмяВнешнейПечатнойФормы" Тогда

  CcылкаВПФ = Справочники.ДополнительныеОтчетыИОбработки.НайтиПоНаименованию("ИмяВнешнейПечатнойФормы", Истина);
  ИдентификаторКомандыПечатнойФормы = "ПротоколСогласованияЦен"; // идентификатор команды, должен соответствовать внешней ПФ
  ДанныеПечатнойФормы = СформироватьВнешнююПечатнуюФорму(Документ1С, CcылкаВПФ, ИдентификаторКомандыПечатнойФормы);

  Результат.Метаданные.DocumentDate   = Документ1С.Дата;
  Результат.Метаданные.DocumentNumber = СокрЛП(Документ1С.Номер);
  Результат.Метаданные.FileName               = ДанныеПечатнойФормы.ИмяФайла;

  Результат.ЗапрашиватьОтветнуюПодпись = Истина;
  Результат.ДвоичныеДанные = Новый ДвоичныеДанные(ДанныеПечатнойФормы.ИмяВременногоФайла);

  УдалитьФайлы(ДанныеПечатнойФормы.ИмяВременногоФайла);

КонецЕсли;
  • стандартными функциями из объектов 1С, например "ПрисоединенныеФайлы.ПолучитьДвоичныеДанныеФайла".