// exchange #2405

var
  // значение опции из конфигурации: "Использование Распоряжения на подкрепление"
  vExch2405_Cfg_Option: boolean = FALSE;

{~Exch2405_LinkDoc203
  прикрепление ЭД "распоряжение на подкрепление" к создаваемому ЭД приложение
  к выписке кредитовое, а так же фильтр строк (и необходимость создания
  доп.ЭД класса 79) для создания доп.ЭД класса 79.
  результат
    =true  - создание всех необходимых ЭД выполнено.
    =false - необходимо создание доп.ЭД 79-го класса (по старому варианту)
              но с учетом переданного массива разрешенных строк.
  параметры:
    aDoc - описание созданного 24-го ЭД (приложение к выписке кредитовое).
            параметр должен быть указан. проверка на NULL не выполняется;
    aDocID - ид.этого документа (для линковки 203-го ЭД).
            параметр должен быть указан. проверка на NULL не выполняется;
    aLines79 - (выход) - массив boolean, соответствующий числу строк ЭД aDoc
                          (+1 или + 2 значения сверх на всякий случай).
                          значение для элементов =true означает, что в доп.ЭД
                          79-го класса нужно создавать соответствующую строку ЭД,
                          если значение массива =false - такую строку в доп.ЭД
                          79-класса создавать не нужно.
                          если узла описания строк в ЭД aDoc не будет найдено,
                          или число строк будет =0, в этой переменной будет
                          возвращено NULL.

  даже если функция выполнятся не должна (если опция в конфигурации ="НЕТ"),
  параметр aLines79 все равно будет инициализирован.

  в результате изменения задания потребовалось, если будет слинкован ЭД
  203-го класса, }
function Exch2405_LinkDoc203( var aDoc: variant;
                          aDocID: integer;
                          var aLines79: variant): boolean;
var
  xBudgetID: string;
  xDocNum: string;
  xXml: Variant;
  xXmlNode: Variant;
  xXMLRoot: variant;
  xXml203: Variant;
  xXml203Node: Variant;
  xDocNodeLines: variant;
  xDocNodeLine: variant;
  xLines79Count: integer;
  xLines79CountCopy: integer;
  xKI_CODE: string;
  xKESI_CODE: string;
  xKDI_CODE: string;
  i,j: integer;
begin

    try
      Result := FALSE;

      { создаем список индексов строк ЭД, которые можно включить в
        доп.ЭД 79 класса. по умолчанию - это все строки исходго ЭД.
        для этого ищем узел, в котором описываются строки ЭД.}
      aLines79      := NULL;
      xLines79Count := 0;
      xDocNodeLines := NULL;
      // ищем узел описания строк
      for i := 0 to aDoc.childNodes.length - 1 do
        if (aDoc.childNodes.items[i].nodeName = 'PAYORDERLINE') then begin
          xDocNodeLines := aDoc.childNodes.items[i];
          // заполняем переменную числа строк количеством всех разрешенных
          // строк, что соответствует числу всех строк в доп.ЭД 79-го класса.
          xLines79Count := xDocNodeLines.childNodes.length;
          if (xLines79Count > 0) then begin
            // создаем массив, соответствующий числу строк ЭД (плюс одна строка)
            aLines79 := VarArrayCreate([0, xLines79Count], varBoolean);
            // по умолчанию заполняем массив - разрешаем все строки
            for j := 0 to xLines79Count - 1 do aLines79[j] := TRUE;
          end;
          BREAK;
        end;
      // сохраняем количество строк в ЭД
      xLines79CountCopy := xLines79Count;

      // если опция в конфиге выключена, то операцию по #2405 не выполняем
      if NOT vExch2405_Cfg_Option then EXIT;

      // операция работает только для VB и IP

      if NOT (aDoc.getAttribute('F_ORIGINAL_TYPE') in ['VB','IP'])
        then EXIT;

      xBudgetID := aDoc.getAttribute('F_BUDGET_ID');
      xDocNum   := aDoc.getAttribute('DOC_NUMBER');

      if ( LENGTH( xDocNum) <= 0) then EXIT;


      { получаем описание настройки из справочника:
        Справочники/Бухгалтерия/Бюджетная классификация с Типом операции -26
        "Перечисление в бюджет".
        если такой опции нет - формируем доп.ЭД 79 по старому.}
      xXml := QueryXml( ' select * from CARRYKBK '
                       +' where OPERTYPE_ID = -26 and budget_id = ?',
                        [ xBudgetID]);
      xXMLRoot := xXML.documentElement;
      if (xXMLRoot.childNodes.Length <> 1) then EXIT;
      xXmlNode := xXMLRoot.childNodes.Item[0];


      { искать ЭД "Распоряжение на подкрепление" (класс 203) на статусе
      "Списано со счета", имеющее порожденное Платежное поручение (13 класс)
      на статусе "Обработка завершена", номер которого в последних разрядах
      включает все цифры номера, указанного в Номере Приложения к выписке
      кредитового, по порядку,"Дата списания" Распоряжения на подкрепление
      должна быть равна "Дате по банку" Приложения к выписке,
      "Сумма подкрепления/перечисления" равна "Сумме выписки" Приложения,
      "Направление платежа"="Перечисление в бюджет".
      (пример соотвтествия номера - номер ПП 711083,
      в Номере Приложения к выписке кредитового - номер 83)}
      xXML203:= QueryXml(  ' select R.* from RESTSTRANSFERORDER R '
                       +' where R.BUDGET_ID = ? and r.dispstatus_id = 87 '
                       +' and R.DIRECTION = 0 and '
                       +' exists (select P.ID from PAYORDER P '
                       +' join PAYORDERLINE PL on PL.PAYORDER_ID = P.ID '
                       +' where P.PARENT_ID = R.DOCUMENT_ID and '
                       +' P.DISPSTATUS_ID = 10 and R.DEBIT_DATE = P.CARRY_DATE '
                       +' and PL.AMOUNT = R.AMOUNT and trim(P.DOC_NUMBER) like ?)',
                      [ xBudgetID, '%' + xDocNum]);
      xXMLRoot := xXML203.documentElement;
      if (xXMLRoot.childNodes.Length <> 1)
        then xXml203Node := NULL
        else xXml203Node := xXMLRoot.childNodes.Item[0];


      { сверяем КВИ+КОСГУ+ДопКИ из справочника со всеми строками ЭД.
        если строка соответствуетКВИ+КОСГУ+ДопКИ, то такую строку не
        нужно создавать в доп.ЭД.79.
        если в результате, все строки, будут соответствовать КВИ+КОСГУ+ДопКИ
        справочника, доп.ЭД 79 не должен быть создан.
        делаем так: когда вычеркиваем строку, уменьшаем счетчик числа
        оставшихся строк. в результате, если счетчик =0, то под.ЭД 79 не
        должен создаваться.}

      xKI_CODE   := DeleteLeftNonsignificantZero( xXmlNode.GetAttribute('KI_CODE'));
      xKESI_CODE := DeleteLeftNonsignificantZero( xXmlNode.GetAttribute('KESI_CODE'));
      xKDI_CODE  := DeleteLeftNonsignificantZero( xXmlNode.GetAttribute('KDI_CODE'));

      for i := 0 to xDocNodeLines.childNodes.length - 1 do begin
        xDocNodeLine := xDocNodeLines.childNodes.items[i];

        if ((xKI_CODE = DeleteLeftNonsignificantZero(
                                xDocNodeLine.getAttribute('KI_CODE')))
            AND (xKESI_CODE = DeleteLeftNonsignificantZero(
                                      xDocNodeLine.getAttribute('KESI_CODE')))
            AND (xKDI_CODE = DeleteLeftNonsignificantZero(
                                      xDocNodeLine.getAttribute('KDI_CODE'))))
          then begin
            // совпадение КВИ+КОСГУ+ДопКИ - исключаем строку для доп.ЭД 79
            aLines79[i] := FALSE;
            DEC( xLines79Count);
            // после доработки задания, если найдена хотя бы одна строка,
            // соответствующая строке справочника (КВИ+КОСГУ+ДопКИ),
            // то доп.ЭД 79-го класса не создаем.
            BREAK;
          end;
      end;//for//



      // если ни осталось ни одной строки для доп.ЭД 79 класса, то такой ЭД
      // не создаем (возвращаем результат = TRUE).
      // после доработки задания, если найдена хотя бы одна строка,
      // соответствующая строке справочника (КВИ+КОСГУ+ДопКИ), то доп.ЭД 79-го
      // класса не создаем.
      if (xLines79CountCopy <> xLines79Count)//(xLines79Count <= 0);
        then Result := TRUE;

      // Линкуем ЭД 203-го класса, если он найден (см.выше),
      // если найдена хотя бы одна строка в ЭД соответствующая строке
      // из справочника
      if Result then
        if VarIsNull( xXml203Node)
          then WriteInfo( 'Дополнительных документов для линковки не найдено.')
          else begin

            ExecProc( 'DOCUMENT',
                      [ 'action', 'link',
                        'class', xXml203Node.GetAttribute('DOCUMENTCLASS_ID'),
                        'ID',  xXml203Node.GetAttribute('ID'),
                        'PARENT_ID', aDocID],
                        xBudgetId);
            WriteInfo( FORMAT( 'Слинкован "Распоряжение на подкрепление" № %s Дата: %s Сумма: %s',
                                [ TRIM( xXml203Node.getAttribute('DOC_NUMBER')),
                                  DateToStr( XmlToDateTime( xXml203Node.getAttribute('DOC_DATE'))),
                                  xXml203Node.GetAttribute('AMOUNT')]),
                       TRUE);

          end;
      except
        ExceptionLog( 'Сбой Un_Exch2405.Exch2405_LinkDoc203');
    end;

end;


{~Exch2405_Initialize
  инициализация переменных для выполнения функций.
  обязательно нужно вызвать этот метод.
  метод вызывается из функции init или main в самом начале выполнения скрипта.
  aConfig - список ini данных из входной xml.
            из настроек выбирается необходимый параметр. если его нет,
            или параметр стоит "нет", дополнительная операция по #2405
            не выполняется.}
procedure Exch2405_Initialize( aConfig: TStringList);
begin

    try
      vExch2405_Cfg_Option :=
           ( LOWERCASE( aConfig.Values( 'Использование Распоряжения на подкрепление'))
             = 'да');

      except
        ExceptionLog( 'Сбой Un_Exch2405.Exch2405_Initialize');
    end;

end;

begin
end.
