{~Exch2600_Build195_By_IK_ZV
  создание ЭД 195го класса при загрузке IK из раздела ZR по exchange #2600.

  параметры
     aZV_XML - описание раздела ZR.
                это первый подэлемент в списке элементов узла IK.
                структура:
                  IK
                    ZV
                    ZVDOC
                    ZVDOCOSN
                    ZVDOCVOZ
                    ZVDOCPOL
                    ZVDOCPOL
                    ZVDOCPOL
                    ...
     aZV_XML_Index - индекс узла ZR в списке элементов узла IK.
                структура:
                  IK
                    ZV         <-- индекс этого узла в списке подузлов IK
                    ZVDOC
                    ZVDOCOSN
                    ZVDOCVOZ
                    ZVDOCPOL
                    ZVDOCPOL
                    ZVDOCPOL
                    ...

     aBudgetId - бюджет загрузки IK
     aFinYear - фин.год загрузки IK
     aCfg_2600_CreateED_AUBU - опция из конфига: создавать справки АУ/БУ.

  в результате будет создан ЭД 195го класса, если все будет этому благоволить.}
procedure Exch2600_Build195_By_IK_ZV( aZV_XML: Variant;
                                      aZV_XML_Index: integer;
                                      aBudgetId: string;
                                      aFinYear: string;
                                      aCfg_2600_CreateED_AUBU: boolean;
                                      aCfgCreateDoc5: boolean;
                                      aChangeKBKto0: boolean;
                                      aCfg_CreateParamAUBU: string);
var
  i,i2: integer;
  xIK_XML: Variant;
  xIK_LS_UBP: string;
  xZV_DocNum: string;
  xZV_DocDate: string;
  xZV_GUID_FK: string;
  xLinesAmount: Variant;
  xLinesAmountStr: string;
  xDocInfo: string;
  xXml: Variant;
  xXmlDoc: Variant;
  xXmlNode: Variant;
  xPay_Org_Code: string;
  xPay_LS_ID: string;
  xPay_Org_ID: string;
  xPay_LS_Xml: Variant;
  xRec_Org_INN: string;
  xRec_Org_KPP: string;
  xRec_Org_ID: string;
  xRec_Org_Xml: Variant;
  xPay_BudgetId: string;
  xRec_LS: string;
  xRec_LS_Xml: Variant;
  xRec_LS_Type: string;
  xRec_BIC_BANK: string;
  xIndexLine_S: integer;
  xIndexLine_E: integer;
  xXmlDocLines: Variant;
  xXmlDocLine: Variant;
  xType_KBK: string;
  xKBK: string;
  xZVDOCPOL: Variant;
  xZVDOCVOZ: Variant;
  xZVDOCOSN: Variant;
  xDoc24Xml: Variant;
  xZVDOCVOZ_GUID: string;
  xZVDOCOSN_DATE_PO: string;
  xDocID: string;
  xXMLFound: integer;
  xCheckKES: boolean;
  xIndustryCodeFound: string;
  xProblemIntoLines2952: boolean;
  xOrgID: string;
  xZVDOCPOL_BS_POL: string;
  xZVDOCPOL_KBK_RCP: string;
  xCheckKVR: boolean;
begin

    try
      xIK_XML    := aZV_XML.parentNode;
      xZV_DocNum := aZV_XML.getAttribute('NOM_ZV');
      xZV_DocDate:= aZV_XML.getAttribute('DATE_ZV');
      xZV_GUID_FK:= aZV_XML.GetAttribute('GUID_FK');
      // поле л/с обязательно
      xIK_LS_UBP := TRIM( VarToStr( xIK_XML.getAttribute('LS_UBP')));


      //------------------------------------------------------------------
      // определение индексов строк ZRST в списке разделов вслед за разделом ZR
      xIndexLine_S  := -1;
      xIndexLine_E  := -1;
      xZVDOCPOL     := NULL;
      for i := 0 to aZV_XML.childNodes.Length - 1 do begin
        xXmlNode := aZV_XML.childNodes.Item[i];
        case xXmlNode.NodeName of
          'ZVDOC':
                  if (xIndexLine_S < 0) then begin
                    xIndexLine_S := i;
                    xIndexLine_E := i;
                    // ищем последний раздел ZRST для секции ZR
                    for i2 := xIndexLine_S + 1 to aZV_XML.childNodes.Length - 1 do begin
                      xXmlNode := aZV_XML.childNodes.Item[ i2];
                      if (xXmlNode.NodeName = 'ZVDOC')
                        then xIndexLine_E := i2
                        else BREAK;
                    end;
//                    BREAK;
                  end;

          // для секции ZV допускаются такие разделы
          'ZVDOCPOL': xZVDOCPOL := xXmlNode;
          'ZVDOCOSN': xZVDOCOSN := xXmlNode;
          'ZVDOCVOZ': xZVDOCVOZ := xXmlNode;

          // прочие разделы - окончание секции ZR
          else BREAK;
        end;//case//
      end;//for//

      if ((xIndexLine_S = -1) OR (xIndexLine_E = -1)) then begin
        WriteInfo( 'Не найдены разделы ZVDOC для секции ZV.');
        EXIT;
      end;
      if VarIsNULL( xZVDOCPOL) then begin
        WriteInfo( 'Не найден раздел ZVDOCPOL для секции ZV.');
        EXIT;
      end;
      // exchange #2892
      // убрана проверка раздела ZVDOCVOZ
//      if VarIsNULL( xZVDOCVOZ) then begin
//        WriteInfo( 'Не найден раздел ZVDOCVOZ для секции ZV.');
//        EXIT;
//      end;
      // exchange #2922
      // убрана проверка раздела ZVDOCOSN
//      if VarIsNULL( xZVDOCOSN) then begin
//        WriteInfo( 'Не найден раздел ZVDOCOSN для секции ZV.');
//        EXIT;
//      end;

      //------------------------------------------------------------------
      // сумма всех строк в валюте выплаты
      xLinesAmount := 0.0;
      for i := xIndexLine_S to xIndexLine_E do begin
        xXmlNode := aZV_XML.childNodes.Item[i];

        xLinesAmount := xLinesAmount
                        + StrToCurrDef( xXmlNode.getAttribute( 'SUM_V'), 0);
      end;//for//
      // поскольку это понадобится в дальнейшем не один раз,
      // преобразуем число в строку здесь
      xLinesAmountStr := FORMAT( '%.2f', [ xLinesAmount]);


      //------------------------------------------------------------------
      // описание искомого ЭД 195го класса
      // это описание отображается в логах как описание ЭД.
      xDocInfo := FORMAT( '"Заявка БУ/АУ на выплату средств" № %s дата %s '
                         +'сумма в валюте выплаты %s, номер л/с %s',
                          [ xZV_DocNum,
                            xZV_DocDate,
                            xLinesAmountStr,
                            xIK_LS_UBP]);
      WriteInfo( FORMAT( 'ЭД %s', [ xDocInfo]),
                TRUE);

                {
      // exchange #3062 - перенос проверки строк в создание эд
      // в результате для ау/бу проверять кбк (CheckKBK) не нужно, поэтому
      // exchange #2952 + exchange #2955 и exchange #2855  не будут выполняться.
      if NOT CheckKBK_All_ZVDOC( aZV_XML, aBudgetID, TRUE)
        then EXIT;
      // exchange #2855
      if NOT CheckIK_ZV_ZVDOC_2855( aZV_XML) then EXIT;
        }

      // 2.3.2.1.	производим поиск ЭД 195 класса в списке ЭД системы
      // (по Номеру заявки, Дате заявки, Сумма документа в валюте выплаты
      // (общая сумма всех строк ЭД «Заявка БУ/АУ на выплату средств»),
      // Номеру лицевого счета (IK.LS_UBP – Счет плательщика).
      // нужно учитывать бюджет загрузки IK.
      // Тип документа в ФК «Заявка на возврат»),
      // exchange #2617
      // здесь необходимо отключать кэш.
      // иначе, если загружаются несколько файлов но с одними
      // и теми же данными, то с кэшировании запрос берется из кеша
      // и на повторных данных срабатывает ложно, поэтому при
      // поиске дублей ЭД кэш необходимо отключать.
      // однако это будет больше нагружать сервер.
      xXML := QueryXml(  ' Select A.* From Document D'
                        +' Left Join aubucashrequest A on A.Document_Id = D.Id'
                        +' Where D.Budget_Id = ? and D.DocumentClass_Id = 195'
                        +' and LTrim(A.Doc_Number) = ? and A.Doc_Date = ?'
                        +' and A.PAYDOC_CODE = ?'
                        +' and a.amount = ?'
                        +' and A.Pay_Account = ?'
                        +' and A.dispstatus_id>-1',
                        [ aBudgetId,
                          xZV_DocNum,
                          StrToDate( xZV_DocDate),
                          'ZV',           // Тип документа в ФК
                          // exchange #2817
                          // возможна проблема с передачей значения как число
                          FORMAT( '%0.2f', [ xLinesAmount]),
                          xIK_LS_UBP],
                        FALSE);
      xXMLFound := xXML.documentElement.childNodes.Length;

      // 2.3.2.1.1.	Если ЭД однозначно найден, записываем в поле Foreign_key,
      // если еще не заполнено, значение IK.ZR.GUID_FK.
      if (xXMLFound = 1) then begin
        xXML := xXml.documentElement.childNodes.Item[0];
        // exchange #3019
        // теперь форенкей нужно заполнять всегда, но делаем обновление
        // только если он отличается
        if (GetNodeAttributeEx( xXML, 'FOREIGN_KEY') <> xZV_GUID_FK)
//        if (LENGTH( TRIM( xXML.GetAttribute( 'FOREIGN_KEY'))) <= 0)
          then UpdateDocumentForegnKey( '195', xXML.GetAttribute( 'ID'), xZV_GUID_FK);
(*
          try
            xDocID := xXML.GetAttribute( 'ID');
            xXml := CreateOleObject('Microsoft.XmlDom');
            xXmlDoc := xXml.appendChild( xXml.createElement('DOCUMENT'));
            xXmlDoc.SetAttribute( 'action', 'update');
            xXmlDoc.SetAttribute( 'class', '195');
            xXmlDoc.SetAttribute( 'ID', xDocID);
            xXmlDoc.setAttribute( 'FOREIGN_KEY', xZV_GUID_FK);

            ExecXml( xXml.xml, aBudgetID);

            except
              WriteInfo( FORMAT( 'Ошибка при обновлении поля GUID_FK: %s',
                                  [ LastException.Message]));
          end;
          *)

        EXIT;
      end;

      // если найдено несколько ЭД, тогда записываем сообщение в лог
      // и переходим к следующему ЭД
      if (xXMLFound > 1) then begin
        WriteLog( FORMAT( 'Найдено несколько подобных ЭД %s - не обрабатывается.',
                         [ xDocInfo]));
        EXIT;
      end;

      // 2.3.2.1.2.	Если не найден, и настройка «Создавать документы БУ/АУ»
      // включена, записывать запись в лог и приступать к обработке
      // следующего документа
      if (xXMLFound <= 0) then begin
        // если настройка выключена - ничего в лог не пишем и обрабатываем файл
        // дальше.
        if NOT aCfg_2600_CreateED_AUBU then begin
          WriteLog( FORMAT( 'ЭД %s - не найден и, по настройке, не будет создан.',
                           [ xDocInfo]));
          EXIT;
        end;
        // логируем что ЭД не найден
        WriteLog( FORMAT( 'ЭД %s не найден и будет создан.',
                          [ xDocInfo]));
      end;

      //------------------------------------------------------------------
      WriteLog( 'Определение плательщика...', TRUE);
      { поиск организации плательщика
        Заполнять ID организации-плательщика и счет плательщика -
        номером счета и ID счета, найденным аналогично SP (#2436+#2516).
          л/с - равный по номеру IK.LS_UBP, без даты закрытия;
          Код организации должен быть равен IK. KOD_UBP_PUBP}
      xPay_Org_Code := TRIM( VarToStr( xIK_XML.getAttribute( 'KOD_UBP_PUBP')));
      xPay_BudgetId:= Exch2436_SearchBudgetID( xPay_Org_Code,
                                               aFinYear,
                                               xIK_LS_UBP,
                                               xPay_LS_ID,
                                               xPay_Org_ID,
                                               // всегда проверяем чтобы л/с
                                               // был без даты закрытия.
                                               TRUE);
      // в случае проблем не создаем ЭД 195го класса
      if (xPay_BudgetId = '') then begin
        WriteInfo( FORMAT(   'Не удалось определить бюджет загрузки по коду организации %s и номеру л/с %s.',
                            [ xPay_Org_Code,
                              xIK_LS_UBP]));
        EXIT;
      end;


      if (xPay_BudgetId <> aBudgetId) then begin
        WriteInfo( FORMAT(   'Не совпадает бюджет найденной организации по коду организации %s и номеру л/с %s с бюджетом загрузки IK файла.',
                            [ xPay_Org_Code,
                              xIK_LS_UBP]));
        EXIT;
      end;

      if (xPay_LS_ID = '') then begin
        WriteInfo( FORMAT(  'Не удалось найти описание л/с по коду организации %s и номеру л/с %s.',
                            [ xPay_Org_Code,
                              xIK_LS_UBP]));
        EXIT;
      end;
      // загружаем описание счета плательщика
      if (GetOrgAccountGetter_ToXML( xPay_LS_Xml, 'id='+xPay_LS_ID) <> 1)
        then begin
          WriteInfo( 'Не удалось прочитать описание найденного л/с в бд.');
          EXIT;
        end;

      //------------------------------------------------------------------
      WriteLog( 'Определение получателя...', TRUE);
      // БИК банка получателя - ZVDOCPOL. BIC_BANK
      xRec_BIC_BANK := TRIM( VarToStr( xZVDOCPOL.getAttribute( 'BIC_BANK')));
      // проверяем в бд наличие банка по бик.
      // если не нашли или нашли несколько - ЭД не создаем
      if (LENGTH( xRec_BIC_BANK) <= 0) then begin
        WriteInfo( 'Не указан банк получателя.');
        EXIT;
      end;
      if (QueryField( 'select count(*) N from bank where bic=?',
                      [ xRec_BIC_BANK],
                      'N') <> '1') then begin
        WriteInfo( FORMAT(  'Не найден банк получателя %s.',
                            [ xRec_BIC_BANK]));
        EXIT;
      end;

      //------------------------------------------------------------------
      // создаем документ Заявка БУ/АУ на выплату средств

        xXml := CreateOleObject('Microsoft.XmlDom');
        xXmlDoc := xXml.appendChild( xXml.createElement('DOCUMENT'));
        xXmlDoc.setAttribute( 'action', 'insert');
        xXmlDoc.setAttribute( 'class', '195');
        xXmlDoc.setAttribute( 'BUDGET_ID', aBudgetID);
        // F_BUDGET_ID и FOREIGN_KEY нужны для проверки документа в
        // подпрограмме ExistsDocument.
        xXmlDoc.setAttribute( 'F_BUDGET_ID', aBudgetID);
        xXmlDoc.setAttribute( 'FOREIGN_KEY', xZV_GUID_FK);
//        xXmlDoc.setAttribute( 'F_ORIGINAL_TYPE',
//                              xDocument.getAttribute( 'F_ORIGINAL_TYPE'));
        // Номер документа	Номер заявки	ZR.NOM_ZR
        xXmlDoc.setAttribute( 'DOC_NUMBER', xZV_DocNum);
        // Дата документа	Дата заявки	ZR.DATE_ZR
        // строка должна быть в формате YYYY-MM-DD
        xXmlDoc.setAttribute( 'DOC_DATE',
                              DateTimeToXml( StrToDate( xZV_DocDate)));
        // тип операции по умолчанию для текущего ЭД
        xXmlDoc.setAttribute( 'OPERTYPE_ID',
                              OperTypeDefaultForClassEx(
                                            xXmlDoc.GetAttribute( 'class')));
        // дата подписания заполняется датой документа
        // строка должна быть в формате YYYY-MM-DD
        xXmlDoc.setAttribute( 'SIGN_DATE',
                              xXmlDoc.getAttribute( 'DOC_DATE'));
        // сумма из всех строк
        xXmlDoc.setAttribute( 'AMOUNT', xLinesAmountStr);
        // Предельная дата исполнения - Не заполняется
        // Обязательство - Не заполняется
        //------------------------------------------------------------------
        // плательщик
        WriteLog( 'Заполняется плательщик.');
        xXmlDoc.setAttribute( 'PAY_ID', xPay_Org_ID);
        // КПП - из файла IK. KPP_UBP
        xXmlDoc.setAttribute( 'PAY_KPP', xIK_XML.getAttribute( 'KPP_UBP'));
        // ИНН плательщика заполнять из организации, ID которой заполняется
        // в этом блоке.
        xXmlDoc.setAttribute( 'PAY_TAXCODE', GetOrgTaxCode( xPay_Org_ID));
        // Наименование - из файла IK.NAME_UBP_PUBP
        xXmlDoc.setAttribute( 'PAY_NAME',
                              VarToStr( xIK_XML.GetAttribute( 'NAME_UBP_PUBP')));
        // описание л/с
        xXmlDoc.setAttribute( 'PAY_ACC_ID' , xPay_LS_ID);
        xXmlDoc.setAttribute( 'PAY_ACCOUNT' , xIK_LS_UBP);
        // описание реквизиитов по ЛС
        xXmlDoc.setAttribute( 'PAY_ACC_ID'     , xPay_LS_Xml.GetAttribute('ORGACCOUNT_ID'));
        xXmlDoc.setAttribute( 'PAY_OFK_NAME'   , xPay_LS_Xml.GetAttribute('ORG_OFK_NAME'));
        xXmlDoc.setAttribute( 'PAY_UFK_NAME'   , xPay_LS_Xml.GetAttribute('ORG_UFK_NAME'));
        xXmlDoc.setAttribute( 'PAY_UFK_ACCOUNT', xPay_LS_Xml.GetAttribute('ORG_UFK_ACCOUNT'));
        xXmlDoc.setAttribute( 'PAY_UFK_ACC_ID' , xPay_LS_Xml.GetAttribute('ORG_UFK_ACC_ID'));
        xXmlDoc.setAttribute( 'PAY_BIC'        , xPay_LS_Xml.GetAttribute('ORG_BIC'));
        xXmlDoc.setAttribute( 'PAY_B_NAME'     , xPay_LS_Xml.GetAttribute('ORG_B_NAME'));
        // Код клиента	IK.KOD_UBP_PUBP
        xXmlDoc.setAttribute( 'CLIENT_CODE', xPay_Org_Code);
        // Код органа ФК	IK.KOD_TOFK
        xXmlDoc.setAttribute( 'FK_CODE',
                              xIK_XML.getAttribute( 'KOD_TOFK'));
        // описание учредителя по коду вышестоящего ГРБС организации плательщика
        xXmlDoc.SetAttribute( 'ORG_ID',
                              GetOrgManagerID( xPay_Org_ID));
        // Ответственные лица определяются по организации плательщику
        // руководитель: код=-2
        UpdateRespersonM1ByOrgID_IntoXML(
              xXmlDoc,
              'CHIEF_',
              xPay_Org_ID,
              ' and Rp.appointment_id = -2 and Rp.Actual_flag=1');
        // гл.бух: код=-3
        UpdateRespersonM1ByOrgID_IntoXML(
              xXmlDoc,
              'BUH_',
              xPay_Org_ID,
              ' and Rp.appointment_id = -3 and Rp.Actual_flag=1');
        //------------------------------------------------------------------
        // получатель
        WriteLog( 'Заполняется получатель.');

        // ИНН контрагента - ZVDOCPOL. INN_POL
        xXmlDoc.setAttribute( 'REC_TAXCODE' ,
                              VarToStr( xZVDOCPOL.getAttribute( 'INN_POL')));
        // КПП контрагента - ZVDOCPOL. KPP_POL
        xXmlDoc.setAttribute( 'REC_KPP',
                              VarToStr( xZVDOCPOL.getAttribute( 'KPP_POL')));
        // Наименование получателя - ZVDOCPOL. NAME_POL
        xXmlDoc.setAttribute( 'REC_NAME',
                              VarToStr( xZVDOCPOL.getAttribute( 'NAME_POL')));
        // ищем организацию и заполняем реквизиты организации
        xRec_Org_Xml := GetOrgByTaxCodeAndKPP_IntoXml( xXmlDoc, 'REC', xRec_Org_ID);
        if NOT VarIsNull( xRec_Org_Xml) then begin
          xXmlDoc.setAttribute( 'REC_ID', xRec_Org_ID);
          { Расчетный счет получателя.
            л/с ищем только если найдена организация.
            Если заполнен ZVDOCPOL.LS_POL, искать среди счетов Организации-получателя
            данный счет среди Актуальных 5, 7, 8, 9 типа, нераспорядительный
            незакрытый.
            Если найден однозначно, подставлять. Поля Орган, осущ.кассовое
            обслуживание, Счет органа, осущ.кассовое обслуживанеивание заполнять
            по нему.
            Если ZVDOCPOL.LS_POL не заполнен, подставлять ZVDOCPOL. BS_POL.
            Искать его среди счетов Организации-получателя среди Актуальных
            незакрытых 3 и 2 типа, нераспорядительный. Если найден однозначно,
            подставлять.
            Если не найден однозначно, записывать значение из отчета без ID.
            если заполнены оба поля, проверяем ZVDOCPOL.LS_POL и если л/с не
            найден, то ZVDOCPOL.LS_POL не проверяем.}

          // тип искомого счета
          xRec_LS_Type := '';
          // ищем л/с по ZVDOCPOL. LS_POL
          xRec_LS := VarToStr( xZVDOCPOL.getAttribute( 'LS_POL'));
          if (LENGTH( xRec_LS) > 0)
            then xRec_LS_Type := '5, 7, 8, 9'
            else begin
              // ищем л/с по ZVDOCPOL. BS_POL
              xRec_LS := VarToStr( xZVDOCPOL.getAttribute( 'BS_POL'));
              if (LENGTH( xRec_LS) > 0)
                then xRec_LS_Type := '2, 3';
            end;

          if (LENGTH( xRec_LS) > 0) then begin
            // подставляем номер счета
            xXmlDoc.setAttribute( 'REC_ACCOUNT', xRec_LS);
            // ищем счет среди счетов организации
            if (GetOrgAccountGetter_ToXML(
                    xRec_LS_Xml,
                     'where=a.account_number=? '
                    +'and a.Close_Date is null '
                    +'and a.DISTRIBUTIVE_FLAG=0 '
                    +'and a.orgacctype_id in (' + xRec_LS_Type + ') '
                    +'and a.org_id=?',
                    [ xRec_LS,
                      xRec_Org_ID]) = 1)
              then begin
                xXmlDoc.setAttribute( 'REC_ACC_ID'     , xRec_LS_Xml.getAttribute('ORGACCOUNT_ID'));
                xXmlDoc.setAttribute( 'REC_UFK_NAME'   , xRec_LS_Xml.getAttribute('ORG_UFK_NAME'));
                xXmlDoc.setAttribute( 'REC_UFK_ACCOUNT', xRec_LS_Xml.getAttribute('ORG_UFK_ACCOUNT'));
                xXmlDoc.setAttribute( 'REC_UFK_ACC_ID' , xRec_LS_Xml.getAttribute('ORG_UFK_ACC_ID'));
              end;
          end;
        end else begin
          // если организация получатель не найдена, то л/с в справочнике
          // не ищем, а в поле номера счета получателя подставляем значение
          // из поля ZVDOCPOL. BS_POL, не зависимо, пустое оно или нет.
          xXmlDoc.setAttribute( 'REC_ACCOUNT',
                                VarToStr( xZVDOCPOL.getAttribute( 'BS_POL')));
        end;

        // БИК банка получателя
        xXmlDoc.setAttribute( 'REC_BIC', xRec_BIC_BANK);
        // Наименование банка получателя - ZVDOCPOL. NAME_BIC
        xXmlDoc.setAttribute( 'REC_B_NAME',
                              VarToStr( xZVDOCPOL.getAttribute( 'NAME_BIC')));
        // Коррсчет банка Получателя (контрагента) ZVDOCPOL. BS_KS_BANK
        xXmlDoc.setAttribute( 'REC_CORACCOUNT',
                              VarToStr( xZVDOCPOL.getAttribute( 'BS_KS_BANK')));
        //------------------------------------------------------------------
        // прочее
        WriteLog( 'Прочее...');
        // берем первую строку
        xXmlNode := aZV_XML.childNodes.Item[ xIndexLine_S];
        // вид платежа - ZVDOC.VID_PL - из первой строки
        // поле в файле обязательное
        xXmlDoc.setAttribute( 'PAYKIND',
                              PayKindSetAsAzk(
                                        xXmlNode.getAttribute( 'VID_PL')));
        // очередность платежа - ZVDOC.SEQ - из первой строки
        // поле в файле обязательное
        xXmlDoc.setAttribute( 'QUEUE_KIND', xXmlNode.getAttribute( 'SEQ'));
        // внешний статус - не выгружен
        xXmlDoc.setAttribute( 'EXTSTATUS_ID', '0');
        // Тип выгружаемого документа	(вид документа в ФК) - Заполняется значением
        // "Заявка на возврат"
        xXmlDoc.setAttribute( 'PAYDOC_CODE', 'ZV');
        // Сумма НДС - значение по умолчанию «0.00»
        xXmlDoc.setAttribute( 'VAT', '0.00');
        //Назначение платежа - ZVDOC. NAZN_PL - из первой строки
        xXmlDoc.setAttribute( 'DESCRIPTION',
                              VarToStr( xXmlNode.getAttribute( 'NAZN_PL')));
        // вид операции - не заполняется
        // вид операции по л/с - не заполняется
        // результат проверки - не заполняется
        // комментарий - не заполняется

        // exchange #2805
        // загрузка поля FAIP
        if NOT ExchImport_FAIP_Code( aZV_XML.getAttribute( 'FAIP_CODE'),
                                     xXmlDoc,
                                     xDocInfo)
          then EXIT;

        //------------------------------------------------------------------
        // Реквизиты возвращаемого документа
        // exchange #2892
        // если раздела ZVDOCVOZ нет, поле GUID считаем незаполненным
        if VarIsNULL( xZVDOCVOZ)
          then xZVDOCVOZ_GUID := ''
          else xZVDOCVOZ_GUID := VarToStr( xZVDOCVOZ.getAttribute( 'GUID'));
        if (LENGTH( xZVDOCVOZ_GUID) <= 0)
          then WriteLog( 'Реквизиты возвращаемого документа не заполняются.')
          else begin
            WriteLog( 'Заполняются реквизиты возвращаемого документа.');
            { Приложение к выписке кредитовое №
              Поиск 24 класса по ZVDOCVOZ .GUID по первым 36 символам Foreign_key.
              Если найден однозначно, заполнять поля, как и при выборе 24 класса
              в ЭД вручную.}
            xDoc24Xml := QueryXml( ' select p.* from payorder p'
                                  +' where p.foreign_key like ?'
                                  +' and p.documentclass_id=24'
                                  +' and p.budget_id=?',
                                   [  xZVDOCVOZ_GUID + '%',
                                      aBudgetID]);
            if (xDoc24Xml.documentElement.childNodes.Length = 1) then begin
              xDoc24Xml := xDoc24Xml.documentElement.childNodes.Item[0];
              xXmlDoc.SetAttribute( 'PRIM_ID',
                                    xDoc24Xml.GetAttribute( 'ID'));
              xXmlDoc.SetAttribute( 'PRIM_DOC_NUMBER',
                                    xDoc24Xml.GetAttribute( 'DOC_NUMBER'));
              xXmlDoc.SetAttribute( 'PRIM_DOC_DATE',
                                    xDoc24Xml.GetAttribute( 'DOC_DATE'));
              xXmlDoc.SetAttribute( 'PRIM_AMOUNT',
                                    xDoc24Xml.GetAttribute( 'AMOUNT'));
              xXmlDoc.SetAttribute( 'PRIM_PAY_TAXCODE',
                                    xDoc24Xml.GetAttribute( 'PAY_TAXCODE'));
              xXmlDoc.SetAttribute( 'PRIM_PAY_KPP',
                                    xDoc24Xml.GetAttribute( 'PAY_KPP'));
              xXmlDoc.SetAttribute( 'PRIM_GUID',
                                    xDoc24Xml.GetAttribute( 'FOREIGN_KEY'));
            end;
          end;
        //------------------------------------------------------------------
        // Идентификатор платежа - не заполняется
        //------------------------------------------------------------------
                              (*
        //------------------------------------------------------------------
        // классификатор получателя для ФК
        //------------------------------------------------------------------
        // exchange #2616 - заполнение новых полей по ТФФ12
        // из раздела ZVDOCPOL
        // exchange #3801
        if DoFill3801_FK_BUDGET_CODE(
                          GetNodeAttributeEx( xZVDOCPOL, 'KBK_RCP'))
          then DoFill2616_FK_BUDGET_CODE_ZV(
                                  aBudgetID,
                                  GetNodeAttributeEx( xZVDOCPOL, 'KBK_RCP'),
                                  xXmlDoc);
                                  *)

        //------------------------------------------------------------------
        // exchange #3014 - поиск отр.кода с учетом учредителя
        // берем значение один раз из шапки и передаем его каждой строке.
        // если учредитель не указан - ищется без учета учредителя.
        // в этом случае, если код есть для уяредителя и для "не указан"
        // то код не будет найден.
        xOrgID := GetNodeAttributeEx( xXmlDoc, 'ORG_ID');

        //------------------------------------------------------------------
        // exchange #2952
        // если будут проблемы с заполнением косгу или Код субсидии
        // в любой строке эд, то взводим флаг xProblemIntoLines2952 в =true.
        // это понадобится для проверки создания эд 194/195 с учетом
        // параметра конфига.
        xProblemIntoLines2952 := FALSE;

        //------------------------------------------------------------------
        { exchange #3081
          классификация получателя/классификация получателя для ФК

          если значение реквизитов: ZVDOCPOL.KBK_RCP не пусто,
          И значение ZVDOCPOL .BS_POL не пусто и соответствует балансовому
          счету (это первые знаки значения ZVDOCPOL. BS_POL справа):
            =«40101»,«40201»,«40204»,«40105»,«40503»,
                то всегда формировать строку значений полей
                «Классификация получателя для ФК» типом «Доходы»:
                с 1 по 3 знак ZVDOCPOL.KBK_RCP в поле «Админ.»,
                с 4 по 20 в «КВД»;

            =«406»,«407»,
                то всегда формировать строку значений полей
                «Классификация получателя» следующим образом (данное условие
                применить при формировании документа по выполнению условия
                внебанковской операции):

            ИНАЧЕ значение полей «Классификация получателя» или
            «Классификация получателя для ФК» не формировать.}
        xZVDOCPOL_KBK_RCP := GetNodeAttributeEx( xZVDOCPOL, 'KBK_RCP');
        if (LENGTH( xZVDOCPOL_KBK_RCP) > 0) then begin
          xZVDOCPOL_BS_POL := GetNodeAttributeEx( xZVDOCPOL, 'BS_POL');
          if (LENGTH( xZVDOCPOL_BS_POL) >= 3) then
            case COPY( xZVDOCPOL_BS_POL, 1, 3) of
              '406',
              '407': begin
                    // «Классификация получателя»
                    if StrIsEmpty( GetNodeAttributeEx( xZVDOCPOL, 'LS_POL'))
                      then begin
                        { Если значение ZVDOCPOL.LS_POL пустое,
                          то в поле «Тип классификации» строки сохранять
                          значение «доходы»,
                          «Направление операции» - «поступления»,
                          значение с 18 по 20 знак реквизита ZVDOCPOL.KBK_RCP
                          сохранять в поле «КОСГУ».}
                        FillLineED_AuBu_by3081( aBudgetId,
                                                xXmlDoc,
                                                xZVDOCPOL_KBK_RCP,
                                                '',
                                                '195',
                                                xCheckKES,
                                                xCheckKVR,
                                                2);
                      end else begin
                        { Если значение ZVDOCPOL.LS_POL непустое,
                          то в поле «Тип классификации» строки сохранять
                          значение «расходы»,
                          «Направление операции» - «восстановление выплат»,
                          значение с 18 по 20 знак реквизита ZVDOCPOL.KBK_RCP
                          сохранять в зависимости от значения параметра
                          добавленного по ФТ-1, в поле «КОСГУ»,
                          если значение параметра «КОСГУ», или «КВР»,
                          если значение параметра «КВР».}
                        FillLineED_AuBu_by3081( aBudgetId,
                                                xXmlDoc,
                                                xZVDOCPOL_KBK_RCP,
                                                '',
                                                '195',
                                                xCheckKES,
                                                xCheckKVR,
                                                3,
                                                GetNodeAttributeEx( xXmlDoc,
                                                                    'REC_ID'));
                      end;

                    // проверка косгу
                    if NOT CheckKES_for_Line_Created_ED_Ex( aBudgetId,
                                                            xXmlDoc,
                                                            'KESR_HEAD_CODE',
                                                            xCheckKES)
                      then xProblemIntoLines2952 := TRUE;
                    // проверка квр
                    if NOT CheckKVR_for_Line_Created_ED_Ex( aBudgetId,
                                                            xXmlDoc,
                                                            'KVR_HEAD_CODE',
                                                            xCheckKVR)
                      then xProblemIntoLines2952 := TRUE;
                  end;

              else
                if (LENGTH( xZVDOCPOL_BS_POL) >= 5) then
                  case COPY( xZVDOCPOL_BS_POL, 1, 5) of
                    '40101',
                    '40201',
                    '40204',
                    '40105',
                    '40503': begin
                          // «Классификация получателя для ФК»
                          // всегда формировать строку значений полей
                          //c типом «Доходы»: с 1 по 3 знак ZVDOCPOL.KBK_RCP
                          // в поле «Админ.», с 4 по 20 в «КВД»;
                          // без проверки кода в бд
                          xXmlDoc.SetAttribute( 'FK_ANAL_KIND', '1');
                          xXmlDoc.SetAttribute( 'FK_BUDGET_CODE',
                                                xZVDOCPOL_KBK_RCP);
                        end;
                  end;//case//
            end;//case//
        end;

        //------------------------------------------------------------------
        // вложенные таблицы
        if (xIndexLine_S <> -1) then begin
          WriteLog( 'Заполняются вложенные документы...');

            // узел списка вложенных документов
            xXmlDocLines:= xXmlDoc.appendChild( xXml.createElement('LINES'));
            for i := xIndexLine_S to xIndexLine_E do begin
              xXmlNode := aZV_XML.childNodes.Item[i];

              // вложенный документ
              xXmlDocLine := xXmlDocLines.appendChild(
                                                xXml.createElement('LINE'));
              // Сумма - ZVDOC.SUM_V
              xXmlDocLine.setAttribute( 'AMOUNT',
                                        xXmlNode.getAttribute( 'SUM_V'));

              // КОСГУ - Последние 3 символа ZVDOC.KBK
              // exchange #2955 + exchange #2952
              // поскольку проверка кбк не выполняется в начале загрузки,
              // проверка переносится сюда.
              // exchange #3081
              // загрузка косгу/квр + новые поля
              FillLineED_AuBu_by3081( aBudgetId,
                                      xXmlDocLine,
                                      xXmlNode.getAttribute( 'KBK'),
                                      xXmlNode.getAttribute( 'TYPE_KBK'),
                                      '195',
                                      xCheckKES,
                                      xCheckKVR,
                                      0,
                                      xPay_Org_ID);
                                      {
              xKBK := xXmlNode.getAttribute( 'KBK');
              if (LENGTH( xKBK) >= 3)
//                then xXmlDocLine.setAttribute( 'KESR_CODE', COPY( xKBK, LENGTH( xKBK) - 2, 3))
//                else xXmlDocLine.setAttribute( 'KESR_CODE', '000');
                then InsertKES_for_Line_Created_ED(
                                          xXmlDocLine,
                                          'KESR_CODE',
                                          // exchange #3062 - унификация кода
                                          DoEncodeKBK_KES( xKBK),
    //                                      COPY( xKBK, LENGTH( xKBK) - 2, 3),
                                          TRUE,
                                          xCheckKES)
                else InsertKES_for_Line_Created_ED(
                                          xXmlDocLine,
                                          'KESR_CODE',
                                          '000',
                                          FALSE,
                                          xCheckKES);


              // exchange #3081 - тип классификации = расходы
              Fill_CR_ANAL_KIND( xXmlDocLine, '10');
              }

              // проверка косгу. если проверка не успешная - эд не создаем
//              if NOT CheckKES_for_Line_Created_ED( aBudgetId,
//                                                   xXmlDocLine,
//                                                   'KESR_CODE',
//                                                   xCheckKES,
//                                                   aChangeKBKto0,
//                                                   'ЭД не создан. %s')
//                then EXIT;
              // exchange #2952
              // здесь проверяя косгу, если кода в бд нет, то он заменяется на 0,
              // по при этом сбрасываем флаг xCheckKES.
              // это нужно для дальнейшей проверки формирования эд
              // если КОСГУ заменен на 0, то это считается проблемой формирования
              // строки
              // exchange #3062
              // исправлена ошибка с заменой кода на 0 и без проверки кода.
              // exchange #3081 - проверка для КВР/косгу
              if NOT CheckKES_or_KVR_AuBu_by3081( aBudgetID,
                                                  xXmlDocLine,
                                                  xCheckKES,
                                                  xCheckKVR,
                                                  0)
                then xProblemIntoLines2952 := TRUE;

              // КВФО
              // 9 – если IK.LS_UBP начинается на 21 или 31,
              // в остальных случаях 8.
              if ((POS( '21', xIK_LS_UBP) = 1) OR (POS( '31', xIK_LS_UBP) = 1))
                then xXmlDocLine.setAttribute( 'FSR_ID', '9')
                else xXmlDocLine.setAttribute( 'FSR_ID', '8');

              // Отраслевой код
              // ищем записи в аналитических строках по л/с плательщика, КВФО, КОСГУ
              // л/с подставлятся должен не как строка счета, а как id счета.
              xXmlDocLine.setAttribute(
                          'INDUSTRYCODE_ID',
                          SearchUnicalIndustryCode(
                                      aBudgetID,
                                      GetNodeAttributeEx( xXmlDocLine, 'FSR_ID'),
                                      GetNodeAttributeEx( xXmlDocLine, 'KESR_CODE'),
                                      xPay_LS_ID,
                                      GetNodeAttributeEx( xXmlDocLine, 'KVR_CODE'),
                                      xCheckKES,
                                      xCheckKVR));

              // Код субсидии	- ZVDOC.ADD_KLASS
              // Искать в справочнике субсидий по коду только среди кодов,
              // у которых учредитель равен Учредителю документа, либо Не указан.
              // Если не заполнено, заполнять системным значением 0 (код 0,
              // тип «Не указан», учредитель «Не указан»).
              // exchange #2987 - дополнительное сообщение
              // exchange #3014 - поиск с учетом учредителя
              xXmlDocLine.setAttribute(
                    'GRANTINVESTMENT_ID',
                    SearchGrandinvestmentCodeEx(
                              aBudgetID,
                              GetNodeAttributeEx( xXmlNode, 'ADD_KLASS'),
                              xIndustryCodeFound,
                              TRUE,
                              xOrgID));

              // если Код субсидии не указан или заменен на 0,
              // то это считается проблемой формирования строки
              if (LENGTH( xIndustryCodeFound) > 0) then
                if (xIndustryCodeFound <> '1')
                  then xProblemIntoLines2952 := TRUE;

              // Назначение платежа	ZVDOC.NAZN_PL
              xXmlDocLine.setAttribute(
                    'DESCRIPTION_LINES',
                    TRIM( VarToStr( xXmlNode.getAttribute( 'NAZN_PL'))));
              // Примечание	Примечание - не заполняется
            end;//for//

        end;
        //------------------------------------------------------------------
        // документ-основание
        WriteLog( 'Заполненяется документ-основание.');
        xXmlDocLines := xXmlDoc.appendChild(
                                xXml.createElement( 'GROUND_DOC'));
        // вложенный документ
        xXmlDocLine := xXmlDocLines.appendChild(
                                xXml.createElement( 'GROUND_DOC'));
        // exchange #2922
        // если раздел ZVDOCOSN не найден, то поля не заполняем
        if NOT VarIsNULL( xZVDOCOSN) then begin
          // Вид документа-основания 		ZVDOCOSN. VID_DO
          xXmlDocLine.SetAttribute( 'KIND',
                                    VarToStr( xZVDOCOSN.GetAttribute( 'VID_DO')));
          // Номер документа основания 		ZVDOCOSN. NOM_DO
          xXmlDocLine.SetAttribute( 'DOC_NUMBER',
                                    VarToStr( xZVDOCOSN.GetAttribute( 'NOM_DO')));
          // Дата документа-основания 		ZVDOCOSN. DATE_DO
          // строка должна быть в формате YYYY-MM-DD
          xZVDOCOSN_DATE_PO := VarToStr( xZVDOCOSN.GetAttribute( 'DATE_DO'));
          if (LENGTH( xZVDOCOSN_DATE_PO) > 0)
            then xXmlDocLine.SetAttribute( 'DOC_DATE',
                                           DateTimeToXml(
                                                StrToDate(
                                                        xZVDOCOSN_DATE_PO)));
        end;

        // Предмет документа-основания - не заполняется
        //------------------------------------------------------------------

      // передаем документ на сервер
      // exchange #2866
      // после создания эд и изменения статуса, создаем эд 5го класса
      // и линкуем с созданным эд 195го класса, если aCfgCreateDoc5=true.

      // exchange #2952
      // если проблем в строках нет, создаем эд как раньше.
      // если проблемы есть, проверяем параметр aCfg_CreateParamAUBU.
      CreateDoc_194_195_by_IK_Ex( aBudgetID,
                                  xXmlDoc,
                                  aCfgCreateDoc5,
                                  xProblemIntoLines2952,
                                  aCfg_CreateParamAUBU);
//      Exec_ChildDoc( aBudgetID, '', xXmlDoc, TRUE, aCfgCreateDoc5);
      //WriteLog( 'ЭД создан на статусе "черновик".');
      except
        ExceptionLog( 'Сбой Un_ImpIK_2600_ZV.Exch2600_Build195_By_IK_ZV');
    end;

end;

begin
end.
