{~Exch2600_Build195_By_IK_SPD
  создание ЭД 199го класса при загрузке IK из раздела SPD по exchange #2600.
  требуется создать ЭД аналогично загрузке SP.
  поэтому функционал из SP

  параметры
     aSPD_XML - описание раздела ZR.
                это первый подэлемент в списке элементов узла IK.
                структура:
                  IK
                    SPD
                    SPRR
                    SPRR
                    SPRR
                    ...
     aSPD_XML_Index - индекс узла ZR в списке элементов узла IK.
                структура:
                  IK
                    SPD      <-- индекс этого узла в списке подузлов IK
                    SPRR
                    SPRR
                    SPRR
                    ...

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

  exchange #3134
  доведение эд 199го до 10го статуса}
procedure Exch2600_Build195_By_IK_SPD( aSPD_XML: Variant;
                                        aSPD_XML_Index: integer;
                                        aBudgetId: string;
                                        aFinYear: string;
                                        //aTO_BUDGET_LEVEL: string;
                                        aCfg_2600_CreateED_AUBU: boolean;
                                        aCfg_ChangeStatusED199to10: boolean);
var
  i,i2: integer;
  xIK_XML: Variant;
  xIK_LS_UBP: string;
  xSPD_DocNum: string;
  xSPD_DocDate: string;
  xSPD_GUID_FK: string;
//  xLinesAmount: Variant;
  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_ID: string;
//  xRec_Org_Xml: Variant;
  xPay_BudgetId: string;
//  xRec_LS: string;
//  xRec_LS_Xml: Variant;
//  xRec_LS_Type: string;
//  xRec_BIC_BANK: string;
//  xSPD_SUM_V_NDS: string;
  xIndexLine_S: integer;
  xIndexLine_E: integer;
  xXmlDocLines: Variant;
//  xXmlDocLine: Variant;
  xXmlOrg: Variant;
  xXmlGRBS: Variant;
  xDocCountExists: integer;
  xSPRRLineCountToDoc: integer;
  xSPD_NameDoc: string;
  xNAME_DOC__: string;
  xDocDescription: string;
  xFirstLine: boolean;
  xXmlAnswer: Variant;
  xDocID: string;
  xXMLFound: integer;
begin

    try
      xIK_XML    := aSPD_XML.parentNode;
      // поле л/с обязательно
      xIK_LS_UBP := TRIM( VarToStr( xIK_XML.getAttribute('LS_UBP')));
      xSPD_DocNum := aSPD_XML.getAttribute('NUM_DOC');
      xSPD_DocDate:= aSPD_XML.getAttribute('DATE_SP');
      xSPD_GUID_FK:= aSPD_XML.GetAttribute('GUID_FK');


      //------------------------------------------------------------------
      // определение индексов строк ZRST в списке разделов вслед за разделом ZR
      xIndexLine_S := -1;
      xIndexLine_E := -1;
      for i := 0 to aSPD_XML.childNodes.Length - 1 do begin
        xXmlNode := aSPD_XML.childNodes.Item[i];
        case xXmlNode.NodeName of
          'SPRR':
                  // exchange #2842
                  // исправлена ошибка определения многих SPRR в одном блоке SPR
                  if (xIndexLine_S < 0) then begin
                    xIndexLine_S := i;
                    xIndexLine_E := i;
                    // последний элемент списка определяем окончанием
//                    xIndexLine_E := aSPD_XML.childNodes.Length - 1;
                    // ищем последний раздел ZRST для секции ZR
                    for i2 := xIndexLine_S + 1 to aSPD_XML.childNodes.Length - 1 do begin
                      xXmlNode := aSPD_XML.childNodes.Item[i2];
                      if (xXmlNode.NodeName = 'SPRR')
                        then xIndexLine_E := i2
                        else BREAK;
                    end;
                    //BREAK;
                  end;
          // прочие разделы - окончание секции ZR
          else BREAK;
        end;//case//
      end;//for//

      if ((xIndexLine_S = -1) OR (xIndexLine_E = -1)) then begin
        WriteInfo( 'Не найдены разделы SPRR для секции SPD.');
        EXIT;
      end;

      //------------------------------------------------------------------
      // описание ЭД
      Exch2436_Builder199Info_By_SP( aSPD_XML, xDocInfo);
      // добавляем к описанию номер л/с
      xDocInfo := FORMAT( '%s, номер л/с %s',
                          [ xDocInfo,
                            xIK_LS_UBP]);
      WriteInfo( FORMAT( 'ЭД %s.', [ xDocInfo]),
                TRUE);

      //------------------------------------------------------------------
      // 2.8.2.1.	производим поиск ЭД 199 класса в списке ЭД системы
      // (по Номеру (SPD.NUM_DOC), Дате (SPD.DATE_SP),
      // Номеру лицевого счета (IK.LS_UBP).
      // нужно учитывать бюджет загрузки IK.
      xXML := QueryXml(  ' Select A.* From Document D'
                        +' Left Join moneytransferorder A on A.Document_Id = D.Id'
                        +' Where D.Budget_Id = ? and D.DocumentClass_Id = 199'
                        +' and LTrim(A.Doc_Number) = ? and A.Doc_Date = ?'
                        +' and A.PAY_ACCOUNT=?'
                        +' and A.dispstatus_id>-1',
                        [ aBudgetId,
                          xSPD_DocNum,
                          StrToDate( xSPD_DocDate),
                          xIK_LS_UBP],
                        FALSE);       // кеш не используем
      xXMLFound := xXML.documentElement.childNodes.Length;

      // 2.8.2.1.1.	Если ЭД однозначно найден, записываем в поле Foreign_key,
      // если еще не заполнено, значение IK.SPD.GUID_FK.
      if (xXMLFound = 1) then begin

        xXML := xXml.documentElement.childNodes.Item[0];
        if (LENGTH( TRIM( xXML.GetAttribute( 'FOREIGN_KEY'))) <= 0) then
          try
            xDocID := xXML.GetAttribute( 'ID');
            xXml := CreateOleObject('Microsoft.XmlDom');
            xXmlDoc := xXml.appendChild( xXml.createElement('DOCUMENT'));
            xXmlDoc.SetAttribute( 'action', 'update');
            xXmlDoc.SetAttribute( 'class', '199');
            xXmlDoc.SetAttribute( 'ID', xDocID);
            xXmlDoc.setAttribute( 'FOREIGN_KEY', xSPD_GUID_FK);

            ExecXml( xXml.xml, aBudgetID);

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

        EXIT;
      end;

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

        EXIT;
      end;

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

          EXIT;
        end;
(*
        // проверяем TO.BUDGET_LEVEL
        if (aTO_BUDGET_LEVEL <> '6') then begin

          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( FORMAT(  'ЭД %s - не удалось прочитать описание найденного л/с в бд.',
                              [ xDocInfo]));
          EXIT;
        end;

      //------------------------------------------------------------------
      WriteLog('Получение данных организации по номеру л/с', True);
      xXmlOrg := QueryXml( ' select * from org where id=?',
                            [ xPay_Org_ID]);
      // доп.проверка результата запроса
      if (xXmlOrg.documentElement.childNodes.Length <> 1) then begin
        WriteInfo( 'Не удалось прочитать описание организации учреждения в бд.');
        EXIT;
      end;
      xXmlOrg := xXmlOrg.documentElement.childNodes.item[0];
      // учредитель - код вышестоящей организации.
      // если поле не заполнено, ищем организацию с кодом "не указано" (id=0)
      WriteLog('Получение данных организации учредителя', True);
      if (LENGTH( GetNodeAttributeEx( xXmlOrg, 'MANAGER_ID')) <= 0)
        then xXmlGRBS := QueryXml( ' select * from org where id=?',
                                    [ '0'])
        else xXmlGRBS := QueryXml( ' select * from org where id=?',
                                    [ xXmlOrg.GetAttribute( 'MANAGER_ID')]);
      // доп.проверка результата запроса
      if (xXmlGRBS.documentElement.childNodes.Length <> 1) then begin
        WriteInfo( 'Не удалось прочитать описание организации учредителя в бд.');
        EXIT;
      end;
      xXmlGRBS := xXmlGRBS.documentElement.childNodes.item[0];

      //------------------------------------------------------------------
      // проверяем новый ЭД
      xDocCountExists := 0;
      if NOT Exch2436_Parse_SPD( aSPD_XML,
                                  aBudgetID,
                                  xIK_LS_UBP, //aLS,
                                  xPay_LS_ID, //aLS_ID,
                                  xDocInfo,
                                  xDocCountExists,
                                  xSPD_NameDoc)
        then EXIT;

      // проверяем строки SPRR на вхождение в ЭД
      xSPRRLineCountToDoc := 0;
//      for i := aSPD_XML_Index + 1 to xIK_XML.childNodes.Length - 1 do begin
      for i := xIndexLine_S to xIndexLine_E do begin
        xXmlNode := aSPD_XML.childNodes.Item[i];
        if Exch2436_Parse_SPRR( xXmlNode,
                                aBudgetID,
                                xIK_LS_UBP, //aLS,
                                xPay_LS_ID, //aLS_ID,
                                xDocInfo,
                                xSPD_NameDoc,
                                xPay_Org_ID)
          then INC( xSPRRLineCountToDoc);
      end;//for//
      if (xSPRRLineCountToDoc <= 0) then begin

        EXIT;
      end;

      //------------------------------------------------------------------
      // создаем ЭД

        Exch2436_Builder199_By_SP( aSPD_XML,
                                   aBudgetID,
                                   xIK_LS_UBP, //aLS,
                                   xPay_LS_ID, //aLS_ID,
                                   xXmlOrg,
                                   xXmlGRBS,
                                   xXmlDoc,
                                   xXmlDocLines,
                                   xDocInfo,
                                   xNAME_DOC__,
                                   xDocDescription,
                                   xFirstLine);
        // добавляем список строк
//        for i := aSPD_XML_Index + 1 to xIK_XML.childNodes.Length - 1 do begin
        for i := xIndexLine_S to xIndexLine_E do begin
          xXmlNode := aSPD_XML.childNodes.Item[i];
          Exch2436_Builder199_Line_By_SP( aBudgetID,
                                          xXmlNode,
                                          xXmlDoc,
                                          xXmlDocLines,
                                          xDocInfo,
                                          xNAME_DOC__,
                                          xDocDescription,
                                          xFirstLine);
        end;//for//

      // Вставка и обработка.


      // exchange #3134
      // добавлено изменение состояния эд если aCfg_ChangeStatusED199to10=true.
      // если aCfg_ChangeStatusED199to10=false, то блокируется изменение
      // статуса эд после создания.
      // это делается в подпрограмме Exec_ChildDoc с помощью дополнительных
      // параметров.
      if aCfg_ChangeStatusED199to10
        then Exec_ChildDoc( aBudgetID,
                            '',
                            xXmlDoc,
                            TRUE,
                            FALSE,
                            '')
        else Exec_ChildDoc( aBudgetID,
                            '',
                            xXmlDoc,
                            TRUE,
                            FALSE,
                            'no_change_status_199=1');

//      ExecXml( xXmlDoc.xml, aBudgetID);
      (*
      xXmlAnswer := CreateOleObject('Microsoft.XmlDom');
      xXmlAnswer.LoadXml( ExecXml( xXmlDoc.xml, aBudgetID));

*)
      WriteInfo( 'ЭД Создан.', True);
      except
        ExceptionLog( 'Сбой Un_ImpIK_2600_SPD.Exch2600_Build195_By_IK_SPD');
    end;

end;

begin
end.
