create or replace package PKG_P8PANELS_CLNTTSKBRD as
  
  /* Формирование набора данных с отобранными событиями */
  procedure CLNEVENTS_LOAD
  (
    CFILTERS                in clob,        -- Фильтры
    CORDERS                 in clob,        -- Сортировки
    NINCLUDE_ACCOUNTS       in number := 1, -- Включать информацию о контрагентах с изображением (0 - нет, 1 - да)
    COUT                    out clob        -- Сериализованная таблица данных
  );
  
  /* Выбор события по рег. номеру */
  procedure CLNEVENTS_SELECT
  (
    NCLNEVENTS              in number,  -- Рег. номер события
    NIDENT                  out number  -- Идентификатор буфера подобранных (списка отмеченных записей, null - не найдено)
  );

  /* Считывание следующего номера события */
  procedure CLNEVENTS_NEXTNUMB_GET
  (
    SPREFIX                 in varchar2, -- Префикс события
    SEVENT_NUMB             out varchar2 -- Номер события
  );
  
  /* Считывание параметров события */
  procedure CLNEVENTS_GET
  (
    NCLNEVENTS              in number,  -- Рег. номер события
    COUT                    out clob    -- Данные о записи события
  );

  /* Инициализация параметров события */
  procedure CLNEVENTS_INIT
  (
    SEVENT_TYPE             in varchar2,  -- Мнемокод типа события
    SPREF                   out varchar2, -- Префикс события
    SNUMB                   out varchar2, -- Номер события
    SSTATUS                 out varchar2, -- Начальный статус
    SINIT_PERSON            out varchar2, -- Сотрудник - инициатор
    SINIT_AUTHNAME          out varchar2  -- Пользователь - инициатор
  );
  
  /* Добавление значений свойств документа */
  procedure CLNEVENTS_PROPS_INSERT
  (
    NCLNEVENTS              in number,   -- Рег. номер события
    SEVENT_TYPE             in varchar2, -- Мнемокод типа события
    CPROPS                  in clob      -- Свойства документа
  );
  
  /* Добавление события */
  procedure CLNEVENTS_INSERT
  (
    SCRN                    in varchar2, -- Наименование каталога
    SPREF                   in varchar2, -- Префикс события
    SNUMB                   in varchar2, -- Номер события
    STYPE                   in varchar2, -- Тип события
    SSTATUS                 in varchar2, -- Статус события
    SPLAN_DATE              in varchar2, -- Дата планируемого начала работ
    SINIT_PERSON            in varchar2, -- Инициатор
    SCLIENT_CLIENT          in varchar2, -- Клиент-инициатор
    SCLIENT_PERSON          in varchar2, -- Сотрудник-инициатор
    SDESCRIPTION            in varchar2, -- Описание
    SREASON                 in varchar2, -- Причина
    CPROPS                  in clob      -- Свойства
  );
  
  /* Исправление события */
  procedure CLNEVENTS_UPDATE
  (
    NCLNEVENTS              in number,   -- Рег. номер события
    SCLIENT_CLIENT          in varchar2, -- Клиент-инициатор
    SCLIENT_PERSON          in varchar2, -- Сотрудник-инициатор
    SDESCRIPTION            in varchar2, -- Описание
    CPROPS                  in clob      -- Свойства
  );
  
  /* Удаление события */
  procedure CLNEVENTS_DELETE
  (
    NCLNEVENTS              in number   -- Рег. номер события
  );
  
  /* Изменение статуса события */
  procedure CLNEVENTS_STATE_CHANGE
  (
    NIDENT                  in out number,       -- Рег. номер отмеченных записей
    NSTEP                   in out number,       -- Шаг выполнения (0-прекратить выполнение, 1,2..- номер шага)
    NEVENT                  in out number,       -- Событие, для отбора исполнителей
    SEVENT_TYPE             in out varchar2,     -- Тип события, для отбора точек перехода и исполнителей
    SEVENT_STAT             in out varchar2,     -- Cтатус события, текущий - для отбора точек перехода, следующий - для отбора исполнителей
    SINIT_PERSON            in out varchar2,     -- Инициатор–сотрудник, для отбора исполнителей
    SINIT_AUTHNAME          in out varchar2,     -- Инициатор–пользователь, для отбора исполнителей
    SCLIENT_CLIENT          in out varchar2,     -- Клиент–организация, для отбора исполнителей
    SCLIENT_PERSON          in out varchar2,     -- Клиент–сотрудник, для отбора исполнителей
    NPOINT                  in out number,       -- Текущая точка маршрута
    NPASS                   in out number,       -- Точка перехода
    NSELECT_EXEC            out number,          -- Признак необходимости выбора исполнителя
    SEXECUTEMETHOD          out varchar2,        -- Мнемокод метода
    SSEND_CLIENT            in varchar2,         -- Направить – организация
    SSEND_DIVISION          in varchar2,         -- Направить – подразделение
    SSEND_POST              in varchar2,         -- Направить – должность
    SSEND_PERFORM           in varchar2,         -- Направить – должность в подразделении
    SSEND_PERSON            in varchar2,         -- Направить – сотрудник
    SSEND_STAFFGRP          in varchar2,         -- Направить – нештатная структура
    SSEND_USER_GROUP        in varchar2,         -- Направить – группа пользователей
    SSEND_USER_NAME         in varchar2,         -- Направить – пользователь
    NSEND_PREDEFINED_EXEC   in number,           -- Переадресация
    NSEND_PREDEFINED_PROC   in number,           -- Процедура выбора предопределенного исполнителя
    SNEXT_STAT              in varchar2 := null, -- Следующий статус (при переносе события)
    SNOTE_HEADER            in varchar2 := null, -- Заголовок примечания (при наличии)
    SNOTE                   in varchar2 := null  -- Примечание (при наличии)
  );
  
  /* Перемещение события */
  procedure CLNEVENTS_MOVE
  (
    NCLNEVENTS              in number,  -- Рег. номер события
    NCRN                    in number   -- Рег. номер каталога-получателя
  );
  
  /* Переадресация события */
  procedure CLNEVENTS_SEND
  (
    NIDENT                  in out number,       -- Рег. номер отмеченных записей
    NSTEP                   in out number,       -- Шаг выполнения
    NEVENT                  in out number,       -- Событие, для отбора исполнителей
    SEVENT_TYPE             in out varchar2,     -- Тип события, для отбора точек перехода и исполнителей
    SEVENT_STAT             in out varchar2,     -- Текущий статус события, для отбора исполнителей
    SINIT_PERSON            in out varchar2,     -- Инициатор–сотрудник, для отбора исполнителей
    SINIT_AUTHNAME          in out varchar2,     -- Инициатор–пользователь, для отбора исполнителей
    SCLIENT_CLIENT          in out varchar2,     -- Клиент–организация, для отбора исполнителей
    SCLIENT_PERSON          in out varchar2,     -- Клиент–сотрудник, для отбора исполнителей
    SEXECUTEMETHOD          out varchar2,        -- Мнемокод метода
    SSEND_CLIENT            in varchar2,         -- Направить – организация
    SSEND_DIVISION          in varchar2,         -- Направить – подразделение
    SSEND_POST              in varchar2,         -- Направить – должность
    SSEND_PERFORM           in varchar2,         -- Направить – должность в подразделении
    SSEND_PERSON            in out varchar2,     -- Направить – сотрудник
    SSEND_STAFFGRP          in varchar2,         -- Направить – нештатная структура
    SSEND_USER_GROUP        in varchar2,         -- Направить – группа пользователей
    SSEND_USER_NAME         in out varchar2,     -- Направить – пользователь
    NSEND_PREDEFINED_EXEC   in number,           -- Переадресация
    NSEND_PREDEFINED_PROC   in number,           -- Процедура выбора предопределенного исполнителя
    SNOTE_HEADER            in varchar2 := null, -- Заголовок примечания (при наличии)
    SNOTE                   in varchar2 := null  -- Примечание (при наличии)
  );
  
  /* Возврат в предыдущую точку события */
  procedure CLNEVENTS_RETURN
  (
    NCLNEVENTS              in number   -- Рег. номер события
  );
  
  /* Считывание маршрутов и исполнителей события */
  procedure CLNEVENTS_GET_INFO_BY_CODE
  (
    SEVNTYPE_CODE           in varchar2, -- Мнемокод типа события
    COUT                    out clob     -- XML с параметрами фильтра по умолчанию
  );
  
  /* Считывание учётных документов события */
  procedure CLNEVENTS_DOCLINKS_GET
  (
    SEVNTYPE_CODE           in varchar2, -- Мнемокод типа события
    COUT                    out clob     -- XML с параметрами фильтра по умолчанию
  );
  
  /* Считывание списка рег. номеров дочерних каталогов (включая основной) */
  procedure CLNEVENTS_SUBCATALOGS_GET
  (
    SCRN_NAME               in varchar2,    -- Наименование каталога
    NSUBCAT                 in number := 0, -- Признак включения подкаталогов (0 - нет, 1 - да)
    SRESULT                 out varchar2    -- Список рег. номеров каталогов
  );
  
  /* Формирование условий отбора фильтра */
  procedure CLNEVENTS_COND;
  
  /* Считывание настройки раздела "События" для пользователя */
  procedure CLNEVENTS_DP_RULES_GET
  (
    COUT                    out clob    -- XML с настройкой раздела
  );
  
  /* Считывание свойств раздела "События" */
  procedure CLNEVENTS_PROPS_GET
  (
    SEVNTYPE_CODE           in varchar2, -- Мнемокод типа события
    COUT                    out clob     -- XML со свойствами раздела
  );
  
  /* Загрузка статусов типа события */
  procedure CLNEVNSTATS_LOAD
  (
    SCLNEVNTYPES            in varchar2, -- Мнемокод типа события
    COUT                    out clob     -- Статусы типа события
  );
  
end PKG_P8PANELS_CLNTTSKBRD;
/
create or replace package body PKG_P8PANELS_CLNTTSKBRD as

  /* Константы - мнемокоды разделов */
  SUNIT_CLNEVENTS           constant PKG_STD.TSTRING := 'ClientEvents';   -- Раздел "События"
  SUNIT_AGNLIST             constant PKG_STD.TSTRING := 'AGNLIST';        -- Раздел "Контрагенты" 
  SUNIT_DP                  constant PKG_STD.TSTRING := 'DocsProperties'; -- Раздел "Свойства документов"
  SSELECTLIST_ACTION        constant PKG_STD.TSTRING := 'P8Panels';       -- Код действия для селектлиста
  
  
  /* Константы - вспомогательные */
  SDATE_PATTERN_HH_MI       constant PKG_STD.TSTRING := 'dd.mm.yyyy hh24:mi'; -- Дата и время без секунд
  
  /* Считывание префикса типа свойства документа */
  function UTL_DP_PREF_TYPE_GET
  (
    NTYPE                   in number,       -- Тип свойства документа
    NSHORT                  in number := 1   -- Признак сокращенного префикса (0 - длинный "SDP", "NDP", "DDP", 1 - сокращенный "S", "N", "D")
  ) return                  varchar2         -- Префикс свойства документа
  is
    SRESULT                 PKG_STD.TSTRING; -- Префикс свойства документа
  begin
    /* Если требуется сокращенный */
    if (NSHORT = 1) then
      /* Тип строка */
      case
        /* Строка */
        when (NTYPE = 0) then
          SRESULT := 'S';
        /* Число или время */
        when ((NTYPE = 1) or (NTYPE = 3)) then
          SRESULT := 'N';
        /* Дата */
        else
          SRESULT := 'D';
      end case;
    else
      /* Тип строка */
      case
        /* Строка */
        when (NTYPE = 0) then
          SRESULT := 'SDP';
        /* Число или время */
        when ((NTYPE = 1) or (NTYPE = 3)) then
          SRESULT := 'NDP';
        /* Дата */
        else
          SRESULT := 'DDP';
      end case;
    end if;
    /* Возвращаем результат */
    return SRESULT;
  end UTL_DP_PREF_TYPE_GET;
  
  /* Считывание отформатированного ID доп. свойства (формат "<SDP|NDP|DDP>_<РЕГ_НОМЕР>") */
  function UTL_DP_FORMATTED_ID_GET
  (
    NTYPE                   in number, -- Тип свойства документа
    NRN                     in number  -- Рег. номер свойства документа
  ) return                  varchar2   -- Отформатированный ID (формат "<SDP|NDP|DDP>_<РЕГ_НОМЕР>")
  is
  begin
    /* Возвращаем результат */
    return  UTL_DP_PREF_TYPE_GET(NTYPE => NTYPE, NSHORT => 0) || '_' || TO_CHAR(NRN);
  end UTL_DP_FORMATTED_ID_GET;
    
  /* Считывание записи события */
  function UTL_CLNEVENTS_GET
  (
    NCOMPANY                in number,         -- Рег. номер организации
    NCLNEVENTS              in number          -- Рег. номер события
  ) return                  CLNEVENTS%rowtype  -- Запись события
  is
    RRESULT                 CLNEVENTS%rowtype; -- Запись события
  begin
    /* Считываем событие */
    begin
      select T.*
        into RRESULT
        from CLNEVENTS T
       where T.RN = NCLNEVENTS
         and T.COMPANY = NCOMPANY;
    exception
      when others then
        P_EXCEPTION(0,
                    'Ошибка считывания записи события с рег. номером (%s).',
                    NCLNEVENTS);
    end;
    /* Возвращаем результат */
    return RRESULT;
  end UTL_CLNEVENTS_GET;
    
  /* Считывание мнемокодов ссылок события */
  procedure UTL_CLNEVENTS_JOINS_GET
  (
    NCLNEVENTS              in number,    -- Рег. номер события,
    STYPE                   out varchar2, -- Мнемокод типа события
    SSTATUS                 out varchar2, -- Мнемокод статуса типа события
    SINIT_PERSON            out varchar2, -- Мнемокод инициатора сотрудника
    SCLIENT_CLIENT          out varchar2, -- Мнемокод клиента (организации)
    SCLIENT_PERSON          out varchar2, -- Мнемокод клиента (сотрудника)
    SSEND_CLIENT            out varchar2, -- Мнемокод направления (организация)
    SSEND_DIVISION          out varchar2, -- Мнемокод направления (подразделение)
    SSEND_POST              out varchar2, -- Мнемокод направления (должность)
    SSEND_PERFORM           out varchar2, -- Мнемокод направления (должность в подразделении)
    SSEND_PERSON            out varchar2, -- Мнемокод направления (сотрудник)
    SSEND_STAFFGRP          out varchar2, -- Мнемокод направления (нештатная структура)
    SSEND_USER_GROUP        out varchar2, -- Мнемокод направления (группа пользователей)
    SSEND_USER_NAME         out varchar2  -- Мнемокод направления (группа пользователь)
  )
  is
  begin
    /* Считываем все мнемокоды */
    begin
      select ET.EVNTYPE_CODE,
             TS.EVNSTAT_CODE,
             F_CLNPERSONS_FORMAT_CODE(IP.COMPANY, IP.CODE),
             CC.CLIENT_CODE,
             F_CLNPERSONS_FORMAT_CODE(CP.COMPANY, CP.CODE),
             SC.CLIENT_CODE,
             ID.CODE,
             PS.CODE,
             F_CLNPSDEP_FORMAT_CODE(PP.COMPANY, PP.CODE),
             F_CLNPERSONS_FORMAT_CODE(SP.COMPANY, SP.CODE),
             SG.CODE,
             UG.CODE,
             UL3.NAME
        into STYPE,
             SSTATUS,
             SINIT_PERSON,
             SCLIENT_CLIENT,
             SCLIENT_PERSON,
             SSEND_CLIENT,
             SSEND_DIVISION,
             SSEND_POST,
             SSEND_PERFORM,
             SSEND_PERSON,
             SSEND_STAFFGRP,
             SSEND_USER_GROUP,
             SSEND_USER_NAME
        from CLNEVENTS      T,
             CLNEVNTYPES    ET,
             CLNEVNTYPSTS   ES,
             CLNEVNSTATS    TS,
             CLNPERSONS     IP,
             CLNCLIENTS     CC,
             CLNPERSONS     CP,
             CLNCLIENTS     SC,
             INS_DEPARTMENT ID,
             CLNPOSTS       PS,
             CLNPSDEP       PP,
             CLNPERSONS     SP,
             FCSTAFFGRP     SG,
             USERGRP        UG,
             USERLIST       UL3
       where T.RN = NCLNEVENTS
         and T.EVENT_TYPE = ET.RN
         and T.EVENT_STAT = ES.RN
         and ES.EVENT_STATUS = TS.RN
         and T.INIT_PERSON = IP.RN(+)
         and T.CLIENT_CLIENT = CC.RN(+)
         and T.CLIENT_PERSON = CP.RN(+)
         and T.SEND_CLIENT = SC.RN(+)
         and T.SEND_DIVISION = ID.RN(+)
         and T.SEND_POST = PS.RN(+)
         and T.SEND_PERFORM = PP.RN(+)
         and T.SEND_PERSON = SP.RN(+)
         and T.SEND_STAFFGRP = SG.RN(+)
         and T.SEND_USER_GROUP = UG.RN(+)
         and T.SEND_USER_AUTHID = UL3.AUTHID(+);
    exception
      when others then
        P_EXCEPTION(0, 'Ошибка считывания записи события с рег. номером (%s).', NCLNEVENTS);
    end;
  end UTL_CLNEVENTS_JOINS_GET;
  
  /* Считывание наименования исполнителя события */
  function UTL_CLNEVENTS_SENDER_GET
  (
    NCLNEVENTS              in number                              -- Рег. номер события
  ) return                  varchar2                               -- Наименование исполнителя
  is
    SRESULT                 PKG_STD.TSTRING;                       -- Наименование исполнителя
    NCOMPANY                PKG_STD.TREF := GET_SESSION_COMPANY(); -- Рег. номер организации
    NAGN_VER                PKG_STD.TREF;                          -- Версия раздела "Контрагенты"
  begin
    /* Считываем версию организации */
    FIND_VERSION_BY_COMPANY(NCOMPANY => NCOMPANY, SUNITCODE => SUNIT_AGNLIST, NVERSION => NAGN_VER);
    /* Считываем наименование исполнителя и аватар (если есть возможность) */
    begin
      select COALESCE(SC_A.AGNABBR,
                      ID.NAME,
                      PP.PSDEP_NAME,
                      PS.NAME,
                      SP_A.AGNABBR,
                      SG.NAME,
                      UG.NAME,
                      SUA.AGNABBR,
                      TA.AGNABBR)
        into SRESULT
        from CLNEVENTS      T,
             CLNCLIENTS     SC,
             AGNLIST        SC_A,
             INS_DEPARTMENT ID,
             CLNPSDEP       PP,
             CLNPOSTS       PS,
             CLNPERSONS     SP,
             AGNLIST        SP_A,
             FCSTAFFGRP     SG,
             USERGRP        UG,
             AGNLIST        TA,
             AGNLIST        SUA
       where T.RN = NCLNEVENTS
         and T.COMPANY = NCOMPANY
         and T.SEND_CLIENT = SC.RN(+)
         and SC.CLIENT_AGENT = SC_A.RN(+)
         and T.SEND_DIVISION = ID.RN(+)
         and T.SEND_PERFORM = PP.RN(+)
         and T.SEND_POST = PS.RN(+)
         and T.SEND_PERSON = SP.RN(+)
         and SP.PERS_AGENT = SP_A.RN(+)
         and T.SEND_STAFFGRP = SG.RN(+)
         and T.SEND_USER_GROUP = UG.RN(+)
         and (T.SEND_USER_AUTHID = SUA.PERS_AUTHID(+) and NAGN_VER = SUA.VERSION(+))
         and (T.AUTHID = TA.PERS_AUTHID(+) and NAGN_VER = TA.VERSION(+));
    exception
      when others then
        SRESULT := null;
    end;
    /* Возвращаем результат */
    return SRESULT;
  end UTL_CLNEVENTS_SENDER_GET;
  
  /* Проверка возможности редактирования события в текущем статусе */
  function UTL_CLNEVENTS_BAN_UPDATE_GET
  (
    NCOMPANY                in number,       -- Рег. номер организации
    NCLNEVENTS              in number        -- Рег. номер события
  ) return                  number           -- Признак запрета исправления события в точке маршрута (0 - нет, 1 - да)
  is
    NRESULT                 PKG_STD.TNUMBER; -- Признак запрета исправления события в точке маршрута (0 - нет, 1 - да)
  begin
    /* Считываем событие */
    begin
      select EP.BAN_UPDATE
        into NRESULT
        from CLNEVENTS  CE,
             EVRTPOINTS EP
       where CE.RN = NCLNEVENTS
         and CE.COMPANY = NCOMPANY
         and EP.EVENT_STATUS = CE.EVENT_STAT;
    exception
      when others then
        P_EXCEPTION(0,
                    'Ошибка считывания записи события с рег. номером (%s).',
                    NCLNEVENTS);
    end;
    /* Возвращаем результат */
    return NRESULT;
  end UTL_CLNEVENTS_BAN_UPDATE_GET;
  
  /* Формирование блока запроса свойств документа и коллекций наименований/типов */
  procedure UTL_CLNEVENTS_DP_QUERY_BLOCK
  (
    NCOMPANY                in number,                                 -- Рег. номер организации
    NCLNEVNTYPES            in number,                                 -- Рег. номер типа события
    NQUERY_POS              in number,                                 -- Признак позиции блока в запросе (0 - блок находится в конце запроса, 1 - за блоком есть параметры)
    CSQL                    out clob,                                  -- Буфер для блока SQL
    TDP_NAMES               in out nocopy PKG_CONTVALLOC1S.TCONTAINER, -- Коллекция с наименованиями
    TDP_TYPES               in out nocopy PKG_CONTVALLOC1S.TCONTAINER  -- Коллекция с типами данных
  )
  is
    SDP_CODE                PKG_STD.TSTRING;                           -- Код свойства документа
  begin
    /* Цикл по свойствам документа раздела */
    for REC in (select CEP.PROPERTY,
                       DP.NAME,
                       DP.FORMAT
                  from CLEVTPROPS CEP,
                       DOCS_PROPS DP
                 where CEP.PRN = NCLNEVNTYPES
                   and CEP.COMPANY = NCOMPANY
                   and CEP.PROPERTY = DP.RN(+)
                 order by TO_CHAR(PROPERTY))
    loop
      /* Формирования кода */
      SDP_CODE := 'DP_' || REC.PROPERTY;
      /* Добавление данных в коллекции */
      PKG_CONTVALLOC1S.PUTS(RCONTAINER => TDP_NAMES, SROWID => SDP_CODE, SVALUE => REC.NAME);
      PKG_CONTVALLOC1S.PUTN(RCONTAINER => TDP_TYPES, SROWID => SDP_CODE, NVALUE => REC.FORMAT);
      /* Формирование запроса */
      PKG_SQL_BUILD.APPEND(SSQL      => CSQL,
                           SELEMENT1 => '              (select COALESCE(V.STR_VALUE, to_char(V.NUM_VALUE), to_char(V.DATE_VALUE))');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '   from DOCS_PROPS_VALS V');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '  where T.RN = V.UNIT_RN(+)');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '    and V.DOCS_PROP_RN(+) = ' || REC.PROPERTY || ') as "' || SDP_CODE || '",');
    end loop;
    /* Если собрали данные */
    if ((CSQL is not null) and (CSQL <> EMPTY_CLOB())) then
      /* Добавляем запятую перед встраиваемым блоком */
      CSQL := ',' || CSQL;
      /* Если блок находится в конце запроса */
      if (NQUERY_POS = 0) then
        /* Удаляем последнюю запятую */
        CSQL := SUBSTR(CSQL, 1, LENGTH(CSQL) - 1);
      end if;
    end if;
  end UTL_CLNEVENTS_DP_QUERY_BLOCK;

  /* Считывание мнемокода статуса типа события по умолчанию */
  function UTL_CLNEVNSTATS_CODE_GET
  ( 
    NCOMPANY                in number,       -- Рег. номер организации
    SEVENT_TYPE             in varchar2      -- Мнемокод типа события
  ) return                  varchar2         -- Мнемокод статуса типа события по умолчанию
  is
    SRESULT                 PKG_STD.TSTRING; -- Мнемокод статуса типа события по умолчанию
  begin
    /* Считываем мнемокод статуса типа события по умолчанию */
    begin
      select TMP.EVNSTAT_CODE
        into SRESULT
        from (select S.EVNSTAT_CODE
                from CLNEVNTYPES  T,
                     CLNEVNTYPSTS TS,
                     CLNEVNSTATS  S
               where T.COMPANY = NCOMPANY
                 and T.EVNTYPE_CODE = SEVENT_TYPE
                 and TS.PRN = T.RN
                 and F_EVRTPOINTS_VALID_START_POINT(T.COMPANY, T.RN, TS.RN, TS.DEFAULT_STATUS) = 1
                 and TS.EVENT_STATUS = S.RN
               order by TS.DEFAULT_STATUS desc,
                        S.EVNSTAT_CODE) TMP
       where ROWNUM = 1;
    exception
      when others then
        SRESULT := null;
    end;
    /* Возвращаем результат */
    return SRESULT;
  end UTL_CLNEVNSTATS_CODE_GET;
  
  /* Считывание описателя документа */
  function UTL_UNITLIST_DESCR_GET
  (
    SUNIT_CODE              in varchar2,                                           -- Код раздела
    NDOCUMENT               in number                                              -- Рег. номер документа в разделе
  ) return                  varchar2                                               -- Описатель
  is
    SRES                    PKG_STD.TLSTRING;                                      -- Буфер для результата
    SDESCR_DEFAULT          PKG_STD.TSTRING := 'Документ <RN> раздела <UNITNAME>'; -- Описатель по умолчанию
    NDOCDESCR_RN            PKG_STD.TREF;                                          -- Рег. номер описателя
    NDESCR_FOUND            PKG_STD.TNUMBER := 1;                                  -- Признак существования описателя
  begin
    /* Считываем рег. номер описателя */
    begin
      select T.RN
        into NDOCDESCR_RN
        from DOCDESCRS T
       where T.UNITCODE = SUNIT_CODE
         and T.USERPROC is not null
         and ROWNUM <= 1;
    exception
      when NO_DATA_FOUND then
        NDESCR_FOUND := 0;
    end;
    /* Если есть и описатель и передан идентификатор документа */
    if ((NDESCR_FOUND = 1) and (NDOCUMENT is not null)) then
      /* Исполним и вернём описатель */
      begin
        SRES := F_DOCDESCRS_GET_DESCRIPTION(SUNITCODE => SUNIT_CODE, NDOCUMENT => NDOCUMENT);
        return SRES;
      exception
        when others then
          return COALESCE(SDESCR_DEFAULT, 'Идентификатор - ' || TO_CHAR(NDOCUMENT));
      end;
    else
      /* Описателя нет, но есть идентификатор документа */
      if (NDOCUMENT is not null) then
        /* Тогда вернём описатель по умолчанию или идентификатор */
        return COALESCE(SDESCR_DEFAULT, 'Идентификатор - ' || TO_CHAR(NDOCUMENT));
      else
        /* Нет ничего */
        return SDESCR_DEFAULT;
      end if;
    end if;
  end UTL_UNITLIST_DESCR_GET;

  /* Формирование набора данных с отобранными событиями */
  procedure CLNEVENTS_DG_GET
  (
    NIDENT                  in number,                             -- Идентификатор отбора
    CFILTERS                in clob,                               -- Фильтры
    CORDERS                 in clob,                               -- Сортировки
    COUT                    out clob                               -- Сериализованная таблица данных
  )
  is
    NCOMPANY                PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса
    RF                      PKG_P8PANELS_VISUAL.TDG_FILTERS;       -- Фильтры
    RO                      PKG_P8PANELS_VISUAL.TDG_ORDERS;        -- Сортировки
    RDG                     PKG_P8PANELS_VISUAL.TDG;               -- Описание таблицы
    RDG_ROW                 PKG_P8PANELS_VISUAL.TDG_ROW;           -- Строка таблицы
    CSQL                    clob;                                  -- Буфер для запроса
    ICURSOR                 integer;                               -- Курсор для исполнения запроса
    SEVSTAT                 PKG_STD.TSTRING;                       -- Буфер для статуса события
    NCLNEVNTYPES            PKG_STD.TREF;                          -- Рег. номер типа события
    SDOC_PREF               PKG_STD.TSTRING;                       -- Префикс события (без пробелов)
    SDOC_NUMB               PKG_STD.TSTRING;                       -- Номер события (без пробелов)
    NCLNEVENTS              PKG_STD.TREF;                          -- Рег. номер события
    SSENDER                 PKG_STD.TSTRING;                       -- Наименование исполнителя
    CDP_QUERY               clob;                                  -- Блок запроса со свойствами документа
    TDP_NAMES               PKG_CONTVALLOC1S.TCONTAINER;           -- Коллекция с наименованиями свойств документа
    TDP_TYPES               PKG_CONTVALLOC1S.TCONTAINER;           -- Коллекция с типами свойств документа
    
    /* Считывание типа события из фильтров */
    function CLNEVNTYPES_GET
    (
      NCOMPANY              in number,                         -- Рег. номер организации
      RFILTERS              in PKG_P8PANELS_VISUAL.TDG_FILTERS -- Фильтры
    ) return                number                             -- Рег. номер типа события
    is
      SCLNEVNTYPES          PKG_STD.TSTRING;                   -- Мнемокод типа события
      NRESULT               PKG_STD.TREF;                      -- Рег. номер типа события
    begin
      /* Обходим коллекцию фильтров */
      for I in RFILTERS.FIRST .. RFILTERS.LAST
      loop
        /* Если это фильтр типа события */
        if (RFILTERS(I).SNAME = 'SEVTYPE_CODE') then
          /* Считываем мнемокод типа события */
          SCLNEVNTYPES := RFILTERS(I).SFROM;
          /* Выходим из цикла */
          exit;
        end if;
      end loop;
      /* Если мнемокод типа события был считан */
      if (SCLNEVNTYPES is not null) then
        /* Считываем рег. номер типа события */
        begin
          select T.RN
            into NRESULT
            from CLNEVNTYPES T
           where T.COMPANY = NCOMPANY
             and T.EVNTYPE_CODE = SCLNEVNTYPES;
        exception
          when others then
            NRESULT := null;
        end;
      end if;
      /* Возвращаем результат */
      return NRESULT;
    end CLNEVNTYPES_GET;
    
    /* Добавление колонок/значений по коллекции свойств документа */
    procedure RDG_FILL_BY_TDP
    (
      RDG                   in out nocopy PKG_P8PANELS_VISUAL.TDG,     -- Описание таблицы (изменяется при добавлении колонки)
      RDG_ROW               in out nocopy PKG_P8PANELS_VISUAL.TDG_ROW, -- Строка таблицы (изменяется при заполнении значений строки)
      TDP_NAMES             in PKG_CONTVALLOC1S.TCONTAINER,            -- Коллекция с наименованиями свойств документа
      TDP_TYPES             in PKG_CONTVALLOC1S.TCONTAINER,            -- Коллекция с типами свойств документа
      NFIRST_NUMB           in number := 1,                            -- Номер первого элемента коллекции
      NLAST_NUMB            in number,                                 -- Номер последнего элемента коллекции
      ICURSOR               in integer := null,                        -- Курсор для исполнения запрос (требуется при заполнении значений строки)
      NACTION               in number := 0                             -- Действие (0 - добавление колонки в таблицу, 1 - заполнение значений строки, 2 - добавление колонки курсора)
    )
    is
      SDP_CODE              PKG_STD.TSTRING;                           -- Код свойства документа
      SDP_NAME              PKG_STD.TSTRING;                           -- Имя свойства документа
      NDP_TYPE              PKG_STD.TNUMBER;                           -- Тип свойства документа
      SDP_PREF              PKG_STD.TSTRING;                           -- Префикс свойства документа
    begin
      /* Получаем код первого элемента */
      SDP_CODE := PKG_CONTVALLOC1S.FIRST_(RCONTAINER => TDP_NAMES);
      /* Цикл по именам доп. свойств */
      for I in NFIRST_NUMB .. NLAST_NUMB
      loop
        /* Получаем код следующего элемента */
        if (I > NFIRST_NUMB) then
          SDP_CODE := PKG_CONTVALLOC1S.NEXT_(RCONTAINER => TDP_NAMES, SROWID => SDP_CODE);
        end if;
        /* Если это добавление колонки курсора */
        if (NACTION = 2) then
          PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => I);
        else
          /* Считываем тип доп. свойства */
          NDP_TYPE := PKG_CONTVALLOC1S.GETN(RCONTAINER => TDP_TYPES, SROWID => SDP_CODE);
          /* Определение префикса типа данных к коду */
          SDP_PREF := UTL_DP_PREF_TYPE_GET(NTYPE => NDP_TYPE);
          /* Если это добавление колонки в таблицу */
          if (NACTION = 0) then
            /* Считываем имя свойства документа */
            SDP_NAME := PKG_CONTVALLOC1S.GETS(RCONTAINER => TDP_NAMES, SROWID => SDP_CODE);
            /* Добавляем колонку таблицы */
            PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
                                                SNAME      => SDP_PREF || SDP_CODE,
                                                SCAPTION   => SDP_NAME,
                                                SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
                                                BVISIBLE   => false);
          else
            PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW      => RDG_ROW,
                                                     SNAME     => SDP_PREF || SDP_CODE,
                                                     ICURSOR   => ICURSOR,
                                                     NPOSITION => I);
          end if;
        end if;
      end loop;
    end RDG_FILL_BY_TDP;
  begin
    /* Очистка коллекций информации о свойствах документа */
    PKG_CONTVALLOC1S.PURGE(RCONTAINER => TDP_NAMES);
    PKG_CONTVALLOC1S.PURGE(RCONTAINER => TDP_TYPES);
    /* Читаем фильтры */
    RF := PKG_P8PANELS_VISUAL.TDG_FILTERS_FROM_XML(CFILTERS => CFILTERS);
    /* Читаем сортировки */
    RO := PKG_P8PANELS_VISUAL.TDG_ORDERS_FROM_XML(CORDERS => CORDERS);
    /* Инициализируем таблицу данных */
    RDG := PKG_P8PANELS_VISUAL.TDG_MAKE();
    /* Считываем рег. номер типа события */
    NCLNEVNTYPES := CLNEVNTYPES_GET(NCOMPANY => NCOMPANY, RFILTERS => RF);
    /* Если тип события не считан */
    if (NCLNEVNTYPES is null) then
      P_EXCEPTION(0,
                  'Ошибка считывания типа события. Фильтр по типу события обязателен.');
    end if;
    /* Описываем колонки таблицы данных */
    PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
                                        SNAME      => 'NRN',
                                        SCAPTION   => 'Рег. номер записи',
                                        SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
                                        BVISIBLE   => false);
    PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
                                        SNAME      => 'NCRN',
                                        SCAPTION   => 'Каталог',
                                        SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
                                        SCOND_FROM => 'BYEV_CRN',
                                        BFILTER    => true,
                                        BVISIBLE   => false);
    PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
                                        SNAME      => 'SEVPREF',
                                        SCAPTION   => 'Префикс',
                                        SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
                                        BVISIBLE   => false);
    PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
                                        SNAME      => 'SEVNUMB',
                                        SCAPTION   => 'Номер',
                                        SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
                                        BVISIBLE   => false);
    PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
                                        SNAME      => 'SPREF_NUMB',
                                        SCAPTION   => 'Префикс и номер',
                                        SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
                                        BORDER     => true,
                                        BVISIBLE   => false);
    PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
                                        SNAME      => 'NEVTYPE',
                                        SCAPTION   => 'Тип события (Рег. номер)',
                                        SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
                                        BVISIBLE   => false);
    PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
                                        SNAME      => 'SEVTYPE_CODE',
                                        SCAPTION   => 'Тип события',
                                        SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
                                        SCOND_FROM => 'BYEV_TYPE',
                                        BFILTER    => true,
                                        BVISIBLE   => false);
    PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
                                        SNAME      => 'DREG_DATE',
                                        SCAPTION   => 'Дата регистрации',
                                        SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_DATE,
                                        BVISIBLE   => false);
    PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
                                        SNAME      => 'DCHANGE_DATE',
                                        SCAPTION   => 'Дата последнего изменения',
                                        SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_DATE,
                                        BORDER     => true,
                                        BVISIBLE   => false);
    PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
                                        SNAME      => 'DEXPIRE_DATE',
                                        SCAPTION   => 'Дата истечения времени нахождения в точке маршрута',
                                        SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_DATE,
                                        BVISIBLE   => false);
    PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
                                        SNAME      => 'DPLAN_DATE',
                                        SCAPTION   => 'Дата начала работ',
                                        SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_DATE,
                                        BORDER     => true,
                                        BVISIBLE   => false);
    PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
                                        SNAME      => 'NINIT_PERSON',
                                        SCAPTION   => 'Инициализатор (Рег. номер)',
                                        SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
                                        BVISIBLE   => false);
    PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
                                        SNAME      => 'SINIT_PERSON',
                                        SCAPTION   => 'Инициализатор',
                                        SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
                                        BVISIBLE   => false);
    PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
                                        SNAME      => 'NEVSTAT',
                                        SCAPTION   => 'Статус (Рег. номер)',
                                        SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
                                        BVISIBLE   => false);
    PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
                                        SNAME      => 'SEVSTAT_NAME',
                                        SCAPTION   => 'Статус',
                                        SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
                                        BVISIBLE   => false);
    PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
                                        SNAME      => 'NSEND_PERSON',
                                        SCAPTION   => 'Получатель (Рег. номер)',
                                        SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
                                        BVISIBLE   => false);
    PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
                                        SNAME      => 'SSEND_PERSON',
                                        SCAPTION   => 'Получатель',
                                        SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
                                        SCOND_FROM => 'BYEV_S_PERSON',
                                        BFILTER    => true,
                                        BVISIBLE   => false);
    PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
                                        SNAME      => 'NAGNLIST_RN',
                                        SCAPTION   => 'Рег. номер контрагенты',
                                        SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
                                        BVISIBLE   => false);
    PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
                                        SNAME      => 'NSEND_DIVISION',
                                        SCAPTION   => 'Подразделение (Рег. номер)',
                                        SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
                                        BVISIBLE   => false);
    PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
                                        SNAME      => 'SSEND_DIVISION',
                                        SCAPTION   => 'Подразделение',
                                        SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
                                        SCOND_FROM => 'BYEV_S_DIVISION',
                                        BFILTER    => true,
                                        BVISIBLE   => false);
    PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
                                        SNAME      => 'NSEND_USRGRP',
                                        SCAPTION   => 'Группа пользователей (Рег. номер)',
                                        SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
                                        BVISIBLE   => false);
    PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
                                        SNAME      => 'SSEND_USRGRP',
                                        SCAPTION   => 'Группа пользователей',
                                        SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
                                        SCOND_FROM => 'BYEV_S_USER_GROUP',
                                        BFILTER    => true,
                                        BVISIBLE   => false);
    PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
                                        SNAME      => 'SEVDESCR',
                                        SCAPTION   => 'Описание',
                                        SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
                                        BVISIBLE   => false);
    PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
                                        SNAME      => 'NCLOSED',
                                        SCAPTION   => 'Аннулировано',
                                        SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
                                        SCOND_FROM => 'BYEV_CLOSED_From',
                                        SCOND_TO   => 'BYEV_CLOSED_To',
                                        BFILTER    => true,
                                        BVISIBLE   => false);
    PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
                                        SNAME      => 'SLINKED_UNIT',
                                        SCAPTION   => 'Учётный раздел',
                                        SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
                                        BVISIBLE   => false);
    PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
                                        SNAME      => 'NLINKED_RN',
                                        SCAPTION   => 'Учётный документ (Рег. номер)',
                                        SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
                                        SCOND_FROM => 'BYEV_LINKED_RN',
                                        BFILTER    => true,
                                        BVISIBLE   => false);
    PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
                                        SNAME      => 'SSENDER',
                                        SCAPTION   => 'Наименование исполнителя',
                                        SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
                                        BVISIBLE   => false);
    /* Формируем блок запроса свойств документа и коллекций наименований/типов */
    UTL_CLNEVENTS_DP_QUERY_BLOCK(NCOMPANY     => NCOMPANY,
                                 NCLNEVNTYPES => NCLNEVNTYPES,
                                 NQUERY_POS   => 0,
                                 CSQL         => CDP_QUERY,
                                 TDP_NAMES    => TDP_NAMES,
                                 TDP_TYPES    => TDP_TYPES);
    /* Если есть свойства документа */
    if (PKG_CONTVALLOC1S.COUNT_(RCONTAINER => TDP_NAMES) <> 0) then
      /* Добавляем колонки по свойствам документа */
      RDG_FILL_BY_TDP(RDG        => RDG,
                      RDG_ROW    => RDG_ROW,
                      TDP_NAMES  => TDP_NAMES,
                      TDP_TYPES  => TDP_TYPES,
                      NLAST_NUMB => PKG_CONTVALLOC1S.COUNT_(RCONTAINER => TDP_NAMES),
                      NACTION    => 0);
    end if;
    /* Обходим данные */
    begin
      /* Добавляем подсказку совместимости */
      CSQL := PKG_SQL_BUILD.COMPATIBLE(SSQL => CSQL);
      /* Формируем запрос */
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => 'select T.RN                                               NRN,');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '       T.CRN                                              NCRN,');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.TRIM_() || '(T.EVENT_PREF)                   SEVPREF,');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.TRIM_() || '(T.EVENT_NUMB)                   SEVNUMB,');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '       T.EVENT_TYPE                                       NEVTYPE,');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '       (select CET.EVNTYPE_CODE');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '          from CLNEVNTYPES CET');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '         where CET.RN = T.EVENT_TYPE');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '           and CET.COMPANY = T.COMPANY)                   SEVTYPE_CODE,');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '       T.REG_DATE                                         DREG_DATE,');      
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '       T.CHANGE_DATE                                      DCHANGE_DATE,');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '       T.EXPIRE_DATE                                      DEXPIRE_DATE,');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '       T.PLAN_DATE                                        DPLAN_DATE,');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '       T.INIT_PERSON                                      NINIT_PERSON,');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '       (select P.CODE');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '          from CLNPERSONS P');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '         where P.RN = T.INIT_PERSON');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '           and P.COMPANY = T.COMPANY)                     SINIT_PERSON,');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '       T.EVENT_STAT                                       NEVSTAT,');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '       (select CES.EVNSTAT_NAME');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '          from CLNEVNSTATS CES');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '         where CES.RN = (select CETS.EVENT_STATUS');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '                           from CLNEVNTYPSTS CETS');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '                          where CETS.RN = T.EVENT_STAT');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '                            and CETS.COMPANY = T.COMPANY)');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '           and CES.COMPANY = T.COMPANY)                   SEVSTAT_NAME,');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '       T.SEND_PERSON                                      NSEND_PERSON,');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '       (select P.CODE');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '          from CLNPERSONS P');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '         where P.RN = T.SEND_PERSON');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '           and P.COMPANY = T.COMPANY)                     SSEND_PERSON,');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '       (select P.PERS_AGENT');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '          from CLNPERSONS P');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '         where P.RN = T.SEND_PERSON');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '           and P.COMPANY = T.COMPANY)                     NAGNLIST_RN,');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '       T.SEND_DIVISION                                    NSEND_DIVISION,');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '       (select D.CODE');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '          from INS_DEPARTMENT D');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '         where D.RN = T.SEND_DIVISION');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '           and D.COMPANY = T.COMPANY)                     SSEND_DIVISION,');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '       T.SEND_USER_GROUP                                  NSEND_USRGRP,');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '       (select UG.CODE');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '          from USERGRP UG');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '         where UG.RN = T.SEND_USER_GROUP');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '           and UG.COMPANY = T.COMPANY)                    SSEND_USRGRP,');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '       T.EVENT_DESCR                                      SEVDESCR,');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '       T.CLOSED                                           NCLOSED,');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '       T.LINKED_UNIT                                      SLINKED_UNIT,');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '       T.LINKED_RN                                        NLINKED_RN,');
      /* Колонка без TRIM, только для корректной сортировки по номеру события */
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '       T.EVENT_PREF || ''-'' || T.EVENT_NUMB              SPREF_NUMB');
      /* Добавление блока запроса для свойств документа */
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => CDP_QUERY);
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '  from CLNEVENTS T');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' where T.COMPANY = :NCOMPANY');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '   and T.RN in (select ID from COND_BROKER_IDSMART where IDENT = :NIDENT)');
      PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => '  %ORDER_BY%');
      /* Учтём сортировки */
      PKG_P8PANELS_VISUAL.TDG_ORDERS_SET_QUERY(RDATA_GRID => RDG,
                                               RORDERS    => RO,
                                               SPATTERN   => '%ORDER_BY%',
                                               CSQL       => CSQL);
      /* Учтём фильтры */
      PKG_P8PANELS_VISUAL.TDG_FILTERS_SET_QUERY(NIDENT     => NIDENT,
                                                NCOMPANY   => NCOMPANY,
                                                SUNIT      => SUNIT_CLNEVENTS,
                                                SPROCEDURE => 'PKG_P8PANELS_CLNTTSKBRD.CLNEVENTS_COND',
                                                RDATA_GRID => RDG,
                                                RFILTERS   => RF);
      /* Разбираем его */
      ICURSOR := PKG_SQL_DML.OPEN_CURSOR(SWHAT => 'SELECT');
      PKG_SQL_DML.PARSE(ICURSOR => ICURSOR, SQUERY => CSQL);
      /* Делаем подстановку параметров */
      PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NCOMPANY', NVALUE => NCOMPANY);
      PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NIDENT', NVALUE => NIDENT);
      /* Описываем структуру записи курсора */
      PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 1);
      PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 2);
      PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 3);
      PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 4);
      PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 5);
      PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 6);
      PKG_SQL_DML.DEFINE_COLUMN_DATE(ICURSOR => ICURSOR, IPOSITION => 7);
      PKG_SQL_DML.DEFINE_COLUMN_DATE(ICURSOR => ICURSOR, IPOSITION => 8);
      PKG_SQL_DML.DEFINE_COLUMN_DATE(ICURSOR => ICURSOR, IPOSITION => 9);
      PKG_SQL_DML.DEFINE_COLUMN_DATE(ICURSOR => ICURSOR, IPOSITION => 10);
      PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 11);
      PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 12);
      PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 13);
      PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 14);
      PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 15);
      PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 16);
      PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 17);
      PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 18);
      PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 19);
      PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 20);
      PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 21);
      PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 22);
      PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 23);
      PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 24);
      PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 25);
      PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 26);
      /* Если есть свойства документа */
      if (PKG_CONTVALLOC1S.COUNT_(RCONTAINER => TDP_NAMES) <> 0) then
        /* Добавляем колонок в курсор по свойствам документа */
        RDG_FILL_BY_TDP(RDG         => RDG,
                        RDG_ROW     => RDG_ROW,
                        TDP_NAMES   => TDP_NAMES,
                        TDP_TYPES   => TDP_TYPES,
                        NFIRST_NUMB => RDG.RCOL_DEFS.COUNT - PKG_CONTVALLOC1S.COUNT_(RCONTAINER => TDP_NAMES),
                        NLAST_NUMB  => RDG.RCOL_DEFS.COUNT - 1,
                        ICURSOR     => ICURSOR,
                        NACTION     => 2);
      end if;
      /* Делаем выборку */
      if (PKG_SQL_DML.EXECUTE(ICURSOR => ICURSOR) = 0) then
        null;
      end if;
      /* Обходим выбранные записи */
      while (PKG_SQL_DML.FETCH_ROWS(ICURSOR => ICURSOR) > 0)
      loop
        /* Считываем рег. номер события */
        PKG_SQL_DML.COLUMN_VALUE_NUM(ICURSOR => ICURSOR, IPOSITION => 1, NVALUE => NCLNEVENTS);
        /* Считываем статус события */
        PKG_SQL_DML.COLUMN_VALUE_STR(ICURSOR => ICURSOR, IPOSITION => 3, SVALUE => SDOC_PREF);
        PKG_SQL_DML.COLUMN_VALUE_STR(ICURSOR => ICURSOR, IPOSITION => 4, SVALUE => SDOC_NUMB);
        PKG_SQL_DML.COLUMN_VALUE_STR(ICURSOR => ICURSOR, IPOSITION => 14, SVALUE => SEVSTAT);
        /* Считываем наименование исполнителя */
        SSENDER := UTL_CLNEVENTS_SENDER_GET(NCLNEVENTS => NCLNEVENTS);
        /* Добавляем колонки с данными */
        RDG_ROW := PKG_P8PANELS_VISUAL.TDG_ROW_MAKE(SGROUP => SEVSTAT);
        /* Заполняем колонки */
        PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NRN', NVALUE => NCLNEVENTS);
        PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'NCRN', ICURSOR => ICURSOR, NPOSITION => 2);
        PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SEVPREF', SVALUE => SDOC_PREF);
        PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SEVNUMB', SVALUE => SDOC_NUMB);
        PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW   => RDG_ROW,
                                            SNAME  => 'SPREF_NUMB',
                                            SVALUE => SDOC_PREF || '-' || SDOC_NUMB);
        PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW      => RDG_ROW,
                                                 SNAME     => 'NEVTYPE',
                                                 ICURSOR   => ICURSOR,
                                                 NPOSITION => 5);
        PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW      => RDG_ROW,
                                                 SNAME     => 'SEVTYPE_CODE',
                                                 ICURSOR   => ICURSOR,
                                                 NPOSITION => 6);
        PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLD(RROW      => RDG_ROW,
                                                 SNAME     => 'DREG_DATE',
                                                 ICURSOR   => ICURSOR,
                                                 NPOSITION => 7);
        PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLD(RROW      => RDG_ROW,
                                                 SNAME     => 'DCHANGE_DATE',
                                                 ICURSOR   => ICURSOR,
                                                 NPOSITION => 8);
        PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLD(RROW      => RDG_ROW,
                                                 SNAME     => 'DEXPIRE_DATE',
                                                 ICURSOR   => ICURSOR,
                                                 NPOSITION => 9);
        PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLD(RROW      => RDG_ROW,
                                                 SNAME     => 'DPLAN_DATE',
                                                 ICURSOR   => ICURSOR,
                                                 NPOSITION => 10);
        PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW      => RDG_ROW,
                                                 SNAME     => 'NINIT_PERSON',
                                                 ICURSOR   => ICURSOR,
                                                 NPOSITION => 11);
        PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW      => RDG_ROW,
                                                 SNAME     => 'SINIT_PERSON',
                                                 ICURSOR   => ICURSOR,
                                                 NPOSITION => 12);
        PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW      => RDG_ROW,
                                                 SNAME     => 'NEVSTAT',
                                                 ICURSOR   => ICURSOR,
                                                 NPOSITION => 13);
        PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SEVSTAT_NAME', SVALUE => SEVSTAT);
        PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW      => RDG_ROW,
                                                 SNAME     => 'NSEND_PERSON',
                                                 ICURSOR   => ICURSOR,
                                                 NPOSITION => 15);
        PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW      => RDG_ROW,
                                                 SNAME     => 'SSEND_PERSON',
                                                 ICURSOR   => ICURSOR,
                                                 NPOSITION => 16);
        PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW      => RDG_ROW,
                                                 SNAME     => 'NAGNLIST_RN',
                                                 ICURSOR   => ICURSOR,
                                                 NPOSITION => 17);
        PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW      => RDG_ROW,
                                                 SNAME     => 'NSEND_DIVISION',
                                                 ICURSOR   => ICURSOR,
                                                 NPOSITION => 18);
        PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW      => RDG_ROW,
                                                 SNAME     => 'SSEND_DIVISION',
                                                 ICURSOR   => ICURSOR,
                                                 NPOSITION => 19);
        PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW      => RDG_ROW,
                                                 SNAME     => 'NSEND_USRGRP',
                                                 ICURSOR   => ICURSOR,
                                                 NPOSITION => 20);
        PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW      => RDG_ROW,
                                                 SNAME     => 'SSEND_USRGRP',
                                                 ICURSOR   => ICURSOR,
                                                 NPOSITION => 21);
        PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW      => RDG_ROW,
                                                 SNAME     => 'SEVDESCR',
                                                 ICURSOR   => ICURSOR,
                                                 NPOSITION => 22);
        PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW      => RDG_ROW,
                                                 SNAME     => 'NCLOSED',
                                                 ICURSOR   => ICURSOR,
                                                 NPOSITION => 23);
        PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW      => RDG_ROW,
                                                 SNAME     => 'SLINKED_UNIT',
                                                 ICURSOR   => ICURSOR,
                                                 NPOSITION => 24);
        PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW      => RDG_ROW,
                                                 SNAME     => 'NLINKED_RN',
                                                 ICURSOR   => ICURSOR,
                                                 NPOSITION => 25);
        PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SSENDER', SVALUE => SSENDER);
        /* Если есть свойства документа */
        if (PKG_CONTVALLOC1S.COUNT_(RCONTAINER => TDP_NAMES) <> 0) then
          /* Заполняем строку по свойствам документа */
          RDG_FILL_BY_TDP(RDG         => RDG,
                          RDG_ROW     => RDG_ROW,
                          TDP_NAMES   => TDP_NAMES,
                          TDP_TYPES   => TDP_TYPES,
                          NFIRST_NUMB => RDG.RCOL_DEFS.COUNT - PKG_CONTVALLOC1S.COUNT_(RCONTAINER => TDP_NAMES),
                          NLAST_NUMB  => RDG.RCOL_DEFS.COUNT - 1,
                          ICURSOR     => ICURSOR,
                          NACTION     => 1);
        end if;
        /* Добавляем строку в таблицу */
        PKG_P8PANELS_VISUAL.TDG_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
      end loop;
      /* Освобождаем курсор */
      PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR);
    exception
      when others then
        PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR);
        raise;
    end;
    /* Сериализуем описание */
    COUT := PKG_P8PANELS_VISUAL.TDG_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => 0);
    /* Очистка коллекций */
    PKG_CONTVALLOC1S.PURGE(RCONTAINER => TDP_NAMES);
    PKG_CONTVALLOC1S.PURGE(RCONTAINER => TDP_TYPES);
  end CLNEVENTS_DG_GET;
  
  /* Считывание контрагентов событий с наличием изображения */
  procedure CLNEVENTS_AGENTS_WIMG_GET
  (
    NIDENT                  in number,       -- Идентификатор отобранных записей событий
    COUT                    out clob         -- Информация о контрагентах с наличием изображения
  )
  is
    RANGLIST                AGNLIST%rowtype; -- Запись контрагента
    
    /* Считывание записи контрагента */
    function GET_AGNLIST_ID
    (
      NRN                   in number        -- Рег. номер контрагента
    ) return                AGNLIST%rowtype  -- Запись контрагента
    is
      RRESULT               AGNLIST%rowtype; -- Запись контрагента
    begin
      /* Считываем запись */
      begin
        select T.* into RRESULT from AGNLIST T where T.RN = NRN;
      exception
        when others then
          RRESULT := null;
      end;
      /* Возвращаем результат */
      return RRESULT;
    end GET_AGNLIST_ID;
  begin
    /* Начинаем формирование XML */
    PKG_XFAST.PROLOGUE(ITYPE => PKG_XFAST.CONTENT_);
    /* Обходим контрагентов событий, у которых есть изображение */
    for REC in (select COALESCE(SC_A.RN, SP_A.RN) RN
                  from CLNEVENTS  T,
                       CLNCLIENTS SC,
                       AGNLIST    SC_A,
                       CLNPERSONS SP,
                       AGNLIST    SP_A
                 where T.RN in (select ID from COND_BROKER_IDSMART where IDENT = NIDENT)
                   and ((T.SEND_CLIENT is not null) or (T.SEND_PERSON is not null))
                   and T.SEND_CLIENT = SC.RN(+)
                   and SC.CLIENT_AGENT = SC_A.RN(+)
                   and T.SEND_PERSON = SP.RN(+)
                   and SP.PERS_AGENT = SP_A.RN(+)
                   and ((DBMS_LOB.GETLENGTH(SC_A.IMAGE) <> 0) or (DBMS_LOB.GETLENGTH(SP_A.IMAGE) <> 0))
                 group by COALESCE(SC_A.RN, SP_A.RN))
    loop
      /* Считываем запись контрагента */
      RANGLIST := GET_AGNLIST_ID(NRN => REC.RN);
      /* Если запись считана */
      if (RANGLIST.RN is not null) then
        /* Добавляем информацию о контрагенте */
        PKG_XFAST.DOWN_NODE(SNAME => 'XAGENTS');
        /* Мнемокод контрагента */
        PKG_XFAST.DOWN_NODE(SNAME => 'SAGNABBR');
        PKG_XFAST.VALUE(SVALUE => RANGLIST.AGNABBR);
        PKG_XFAST.UP();
        /* Изображение контрагента */
        PKG_XFAST.DOWN_NODE(SNAME => 'BIMAGE');
        PKG_XFAST.VALUE(LBVALUE => RANGLIST.IMAGE);
        PKG_XFAST.UP();
        PKG_XFAST.UP();
      end if;
    end loop;
    /* Сериализуем */
    COUT := PKG_XFAST.SERIALIZE_TO_CLOB();
    /* Завершаем формирование XML */
    PKG_XFAST.EPILOGUE();
  end CLNEVENTS_AGENTS_WIMG_GET;
  
  /* Загрузка информации о событиях */
  procedure CLNEVENTS_LOAD
  (
    CFILTERS                in clob,        -- Фильтры
    CORDERS                 in clob,        -- Сортировки
    NINCLUDE_ACCOUNTS       in number := 1, -- Включать информацию о контрагентах с изображением (0 - нет, 1 - да)
    COUT                    out clob        -- Сериализованная информация о событиях
  )
  is
    NIDENT                  PKG_STD.TREF;   -- Идентификатор отбора
    CCLNEVENTS              clob;           -- Информация о событиях
    CAGNLIST_WITH_IMAGE     clob;           -- Информация о контрагентах с изображением
  begin
    /* Генерируем идентификатор */
    NIDENT := GEN_IDENT();
    /* Считываем данные о событиях */
    CLNEVENTS_DG_GET(CFILTERS     => CFILTERS,
                     CORDERS      => CORDERS,
                     COUT         => CCLNEVENTS,
                     NIDENT       => NIDENT);
    /* Если требуется включать информацию о контрагентах */
    if (NINCLUDE_ACCOUNTS = 1) then
      /* Считываем информацию о контрагентах с наличием изображения */
      CLNEVENTS_AGENTS_WIMG_GET(NIDENT => NIDENT, COUT => CAGNLIST_WITH_IMAGE);
    end if;
    /* Начинаем формирование XML */
    PKG_XFAST.PROLOGUE(ITYPE => PKG_XFAST.CONTENT_);
    /* Открываем корень */
    PKG_XFAST.DOWN_NODE(SNAME => 'XDATA');
    /* Открываем события */
    PKG_XFAST.DOWN_NODE(SNAME => 'XCLNEVENTS');
    /* Описываем события */
    PKG_XFAST.VALUE_XML(LCVALUE => CCLNEVENTS);
    /* Закрываем события */
    PKG_XFAST.UP();
    /* Если требуется включать информацию о контрагентах */
    if (NINCLUDE_ACCOUNTS = 1) then
      /* Открываем информацию о контрагентах с изображением */
      PKG_XFAST.DOWN_NODE(SNAME => 'XAGENTS_WITH_IMG');
      /* Описываем контрагентов */
      PKG_XFAST.VALUE_XML(LCVALUE => CAGNLIST_WITH_IMAGE);
      /* Закрываем контрагентов */
      PKG_XFAST.UP();
    end if;
    /* Закрываем корень */
    PKG_XFAST.UP();
    /* Сериализуем */
    COUT := PKG_XFAST.SERIALIZE_TO_CLOB();
    /* Завершаем формирование XML */
    PKG_XFAST.EPILOGUE();
  exception
    when others then
      /* Завершаем формирование XML */
      PKG_XFAST.EPILOGUE();
      /* Вернем ошибку */
      PKG_STATE.DIAGNOSTICS_STACKED();
      P_EXCEPTION(0, PKG_STATE.SQL_ERRM());
  end CLNEVENTS_LOAD;
  
  /* Выбор события по рег. номеру */
  procedure CLNEVENTS_SELECT
  (
    NCLNEVENTS              in number,                             -- Рег. номер события
    NIDENT                  out number                             -- Идентификатор буфера подобранных (списка отмеченных записей, null - не найдено)
  )
  is
    NCOMPANY                PKG_STD.TREF := GET_SESSION_COMPANY(); -- Рег. номер организации
    NSELECTLIST             PKG_STD.TREF;                          -- Рег. номер добавленной записи буфера подобранных
    NCRN                    PKG_STD.TREF;                          -- Рег. номер каталога
    
    /* Считывание каталога события */
    function CLNEVENTS_CRN_GET
    (
      NCLNEVENTS            in number     -- Рег. номер события
    ) return                number        -- Рег. номер каталога события
    is
      NRESULT               PKG_STD.TREF; -- Рег. номер каталога события
    begin
      /* Считываем каталог события */
      begin
        select E.CRN into NRESULT from CLNEVENTS E where E.RN = NCLNEVENTS;
      exception
        when others then
          NCRN := null;
      end;
      /* Возвращаем результат */
      return NRESULT;
    end CLNEVENTS_CRN_GET;
  begin
    /* Считываем рег. номер каталога события */
    NCRN := CLNEVENTS_CRN_GET(NCLNEVENTS => NCLNEVENTS);
    /* Если каталог считан */
    if (NCRN is not null) then
      /* Сформируем идентификатор буфера */
      if (NIDENT is null) then
        NIDENT := GEN_IDENT();
      end if;
      /* Добавим подобранное в список отмеченных записей */
      P_SELECTLIST_BASE_INSERT(NIDENT       => NIDENT,
                               NCOMPANY     => NCOMPANY,
                               NDOCUMENT    => NCLNEVENTS,
                               SUNITCODE    => SUNIT_CLNEVENTS,
                               SACTIONCODE  => null,
                               NCRN         => NCRN,
                               NDOCUMENT1   => null,
                               SUNITCODE1   => null,
                               SACTIONCODE1 => null,
                               NRN          => NSELECTLIST);
    end if;
  end CLNEVENTS_SELECT;
  
  /* Считывание следующего номера события */
  procedure CLNEVENTS_NEXTNUMB_GET
  (
    SPREFIX                 in varchar2,                           -- Префикс события
    SEVENT_NUMB             out varchar2                           -- Номер события
  )
  is
    NCOMPANY                PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса
  begin
    /* Считываем следующий номер */
    SEVENT_NUMB := GET_CLNEVENTS_NEXTNUMB(NCOMPANY => NCOMPANY, SPREF => SPREFIX);
  end CLNEVENTS_NEXTNUMB_GET;
  
  /* Считывание параметров события */
  procedure CLNEVENTS_GET
  (
    NCLNEVENTS              in number,                             -- Рег. номер события
    COUT                    out clob                               -- Данные о записи события
  )
  is
    NCOMPANY                PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса
    RCLNEVENTS              CLNEVENTS%rowtype;                     -- Запись события
    SCRN                    PKG_STD.TSTRING;                       -- Наименование каталога
    STYPE                   PKG_STD.TSTRING;                       -- Мнемокод типа события
    SSTATUS                 PKG_STD.TSTRING;                       -- Мнемокод статуса типа события
    SINIT_PERSON            PKG_STD.TSTRING;                       -- Мнемокод инициатора сотрудника
    SCLIENT_CLIENT          PKG_STD.TSTRING;                       -- Мнемокод клиента (организации)
    SCLIENT_PERSON          PKG_STD.TSTRING;                       -- Мнемокод клиента (сотрудника)
    SSEND_CLIENT            PKG_STD.TSTRING;                       -- Мнемокод направления (организация)
    SSEND_DIVISION          PKG_STD.TSTRING;                       -- Мнемокод направления (подразделение)
    SSEND_POST              PKG_STD.TSTRING;                       -- Мнемокод направления (должность)
    SSEND_PERFORM           PKG_STD.TSTRING;                       -- Мнемокод направления (должность в подразделении)
    SSEND_PERSON            PKG_STD.TSTRING;                       -- Мнемокод направления (сотрудник)
    SSEND_STAFFGRP          PKG_STD.TSTRING;                       -- Мнемокод направления (нештатная структура)
    SSEND_USER_GROUP        PKG_STD.TSTRING;                       -- Мнемокод направления (группа пользователей)
    SSEND_USER_NAME         PKG_STD.TSTRING;                       -- Мнемокод направления (группа пользователь)
    SDP_FORMATTED_ID        PKG_STD.TSTRING;                       -- Отформатированный ID свойства документа
  begin
    /* Считываем запись события */
    RCLNEVENTS := UTL_CLNEVENTS_GET(NCOMPANY => NCOMPANY, NCLNEVENTS => NCLNEVENTS);
    /* Считываем наименование каталога */
    FIND_ACATALOG_RN(NFLAG_SMART => 0,
                     NCOMPANY    => NCOMPANY,
                     NVERSION    => null,
                     SUNITCODE   => SUNIT_CLNEVENTS,
                     NRN         => RCLNEVENTS.CRN,
                     SNAME       => SCRN);
    /* Считываем мнемокоды связанных записей */
    UTL_CLNEVENTS_JOINS_GET(NCLNEVENTS       => RCLNEVENTS.RN,
                            STYPE            => STYPE,
                            SSTATUS          => SSTATUS,
                            SINIT_PERSON     => SINIT_PERSON,
                            SCLIENT_CLIENT   => SCLIENT_CLIENT,
                            SCLIENT_PERSON   => SCLIENT_PERSON,
                            SSEND_CLIENT     => SSEND_CLIENT,
                            SSEND_DIVISION   => SSEND_DIVISION,
                            SSEND_POST       => SSEND_POST,
                            SSEND_PERFORM    => SSEND_PERFORM,
                            SSEND_PERSON     => SSEND_PERSON,
                            SSEND_STAFFGRP   => SSEND_STAFFGRP,
                            SSEND_USER_GROUP => SSEND_USER_GROUP,
                            SSEND_USER_NAME  => SSEND_USER_NAME);
    /* Формируем данные на выход */
    PKG_XFAST.PROLOGUE(ITYPE => PKG_XFAST.CONTENT_);
    PKG_XFAST.DOWN_NODE(SNAME => 'XDATA');
    PKG_XFAST.DOWN_NODE(SNAME => 'XEVENT');
    PKG_XFAST.ATTR(SNAME => 'SCRN', SVALUE => SCRN);
    PKG_XFAST.ATTR(SNAME => 'NCLOSED', NVALUE => RCLNEVENTS.CLOSED);
    PKG_XFAST.ATTR(SNAME => 'SPREF', SVALUE => RCLNEVENTS.EVENT_PREF);
    PKG_XFAST.ATTR(SNAME => 'SNUMB', SVALUE => RCLNEVENTS.EVENT_NUMB);
    PKG_XFAST.ATTR(SNAME => 'STYPE', SVALUE => STYPE);
    PKG_XFAST.ATTR(SNAME => 'SSTATUS', SVALUE => SSTATUS);
    PKG_XFAST.ATTR(SNAME => 'SDESCRIPTION', SVALUE => RCLNEVENTS.EVENT_DESCR);
    PKG_XFAST.ATTR(SNAME => 'SCLIENT_CLIENT', SVALUE => SCLIENT_CLIENT);
    PKG_XFAST.ATTR(SNAME => 'SCLIENT_PERSON', SVALUE => SCLIENT_PERSON);
    PKG_XFAST.ATTR(SNAME => 'SPLAN_DATE', SVALUE => TO_CHAR(RCLNEVENTS.PLAN_DATE, SDATE_PATTERN_HH_MI));
    PKG_XFAST.ATTR(SNAME => 'SINIT_PERSON', SVALUE => SINIT_PERSON);
    PKG_XFAST.ATTR(SNAME => 'SINIT_AUTHID', SVALUE => RCLNEVENTS.INIT_AUTHID);
    PKG_XFAST.ATTR(SNAME => 'SREASON', SVALUE => RCLNEVENTS.REASON);
    PKG_XFAST.ATTR(SNAME => 'SSEND_CLIENT', SVALUE => SSEND_CLIENT);
    PKG_XFAST.ATTR(SNAME => 'SSEND_DIVISION', SVALUE => SSEND_DIVISION);
    PKG_XFAST.ATTR(SNAME => 'SSEND_POST', SVALUE => SSEND_POST);
    PKG_XFAST.ATTR(SNAME => 'SSEND_PERFORM', SVALUE => SSEND_PERFORM);
    PKG_XFAST.ATTR(SNAME => 'SSEND_PERSON', SVALUE => SSEND_PERSON);
    PKG_XFAST.ATTR(SNAME => 'SSEND_STAFFGRP', SVALUE => SSEND_STAFFGRP);
    PKG_XFAST.ATTR(SNAME => 'SSEND_USER_GROUP', SVALUE => SSEND_USER_GROUP);
    PKG_XFAST.ATTR(SNAME => 'SSEND_USER_NAME', SVALUE => SSEND_USER_NAME);
    /* Цикл добавления свойств документа события */
    for REC in (select DPV.*,
                       DP.FORMAT,
                       DP.DATA_SUBTYPE
                  from CLEVTPROPS      CEP,
                       CLNEVNTYPES     CET,
                       DOCS_PROPS_VALS DPV,
                       DOCS_PROPS      DP
                 where CEP.PRN = CET.RN
                   and CET.EVNTYPE_CODE = STYPE
                   and CEP.COMPANY = NCOMPANY
                   and CEP.PROPERTY = DPV.DOCS_PROP_RN(+)
                   and CEP.PROPERTY = DP.RN(+)
                   and DPV.UNIT_RN = NCLNEVENTS)
    loop
      /* Считываем отформатированный ID свойства документа */
      SDP_FORMATTED_ID := UTL_DP_FORMATTED_ID_GET(NTYPE => REC.FORMAT, NRN => REC.DOCS_PROP_RN);
      /* Исходим от типа свойства документа */
      case
        /* Строка */
        when (REC.FORMAT = 0) then
          PKG_XFAST.ATTR(SNAME => SDP_FORMATTED_ID, SVALUE => REC.STR_VALUE);
        /* Число */
        when ((REC.FORMAT = 1) or (REC.FORMAT = 3)) then
          PKG_XFAST.ATTR(SNAME => SDP_FORMATTED_ID, NVALUE => REC.NUM_VALUE);
        /* Дата */
        else
          PKG_XFAST.ATTR(SNAME => SDP_FORMATTED_ID, DVALUE => REC.DATE_VALUE, IFORMAT => REC.DATA_SUBTYPE);
      end case;
    end loop;
    PKG_XFAST.UP();
    PKG_XFAST.UP();
    /* Сериализуем в CLOB */
    COUT := PKG_XFAST.SERIALIZE_TO_CLOB();
    PKG_XFAST.EPILOGUE();
  exception
    when others then
      /* Завершаем формирование XML */
      PKG_XFAST.EPILOGUE();
      /* Вернем ошибку */
      PKG_STATE.DIAGNOSTICS_STACKED();
      P_EXCEPTION(0, PKG_STATE.SQL_ERRM());
  end CLNEVENTS_GET;
  
  /* Инициализация параметров события */
  procedure CLNEVENTS_INIT
  (
    SEVENT_TYPE             in varchar2,                           -- Мнемокод типа события
    SPREF                   out varchar2,                          -- Префикс события
    SNUMB                   out varchar2,                          -- Номер события
    SSTATUS                 out varchar2,                          -- Начальный статус
    SINIT_PERSON            out varchar2,                          -- Сотрудник - инициатор
    SINIT_AUTHNAME          out varchar2                           -- Пользователь - инициатор
  )
  is
    NCOMPANY                PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса
    NEVENT_TYPE             PKG_STD.TREF;                          -- Рег. номер типа события
    SOWNER_AGENT_RN         PKG_STD.TSTRING;                       -- Рег. номер работодателя сотрудника
    STAB_PREF               PKG_STD.TSTRING;                       -- Префикс табельного номера сотрудника
    STAB_NUMB               PKG_STD.TSTRING;                       -- Таблеьный номер сотрудника
    
    /* Считывание префикса типа события */
    function CLNEVNTYPES_PREF_GET
    (
      NCOMPANY              in number,       -- Рег. номер организации
      SEVENT_TYPE           in varchar2      -- Мнемокод типа события
    ) return                varchar2         -- Префикс типа события
    is
      SRESULT               PKG_STD.TSTRING; -- Префикс типа события
    begin
      /* Считываем префикс типа события */
      begin
        select T.EVENT_PREF
          into SRESULT
          from CLNEVNTYPES T
         where T.EVNTYPE_CODE = SEVENT_TYPE
           and T.COMPANY = NCOMPANY;
      exception
        when NO_DATA_FOUND then
          SRESULT := null;
      end;
      /* Возвращаем результат */
      return SRESULT;
    end CLNEVNTYPES_PREF_GET;
  begin
    /* Определяем рег. номер типа события */
    FIND_CLNEVNTYPES_CODE(NFLAG_SMART => 0, NCOMPANY => NCOMPANY, SEVNTYPE_CODE => SEVENT_TYPE, NRN => NEVENT_TYPE);
    /* Считываем префикс из параметра */
    SPREF := GET_OPTIONS_STR(SCODE => 'EventPrefix', NCOMP_VERS => NCOMPANY);
    /* Если префикс не указан в параметре и задан тип события */
    if ((SPREF is null) and (SEVENT_TYPE is not null)) then
      /* Считываем префикс типа события */
      SPREF := CLNEVNTYPES_PREF_GET(NCOMPANY => NCOMPANY, SEVENT_TYPE => SEVENT_TYPE);
    end if;
    /* Если префикс определен */
    if (SPREF is not null) then
      /* Считываем номер */
      SNUMB := GET_CLNEVENTS_NEXTNUMB(NCOMPANY => NCOMPANY, SPREF => SPREF);
    end if;
    /* Определим начальный статус */
    begin
      select T.SEVNSTAT_CODE
        into SSTATUS
        from V_CLNEVNTYPSTS_FOR_EVENTS T
       where T.NPRN = NEVENT_TYPE
         and ROWNUM <= 1
       order by T.NDEFAULT_STATUS desc,
                T.SEVNSTAT_CODE;
    exception
      when NO_DATA_FOUND then
        P_EXCEPTION(0,
                    'Для событий типа "%s" не определена начальная точка маршрута.',
                    SEVENT_TYPE);
    end;
    /* Считываем сотрудника текущего пользователя */
    FIND_PERSON_AUTHID(SPERSON      => SINIT_PERSON,
                       SOWNER_AGENT => SOWNER_AGENT_RN,
                       STAB_PREF    => STAB_PREF,
                       STAB_NUMB    => STAB_NUMB);
    /* Считываем имя пользователя */
    FIND_USERLIST_BY_AUTHID(NFLAG_SMART => 1, SAUTHID => UTILIZER, SNAME => SINIT_AUTHNAME);
  end CLNEVENTS_INIT;
  
  /* Добавление значений свойств документа */
  procedure CLNEVENTS_PROPS_INSERT
  (
    NCLNEVENTS              in number,                             -- Рег. номер события
    SEVENT_TYPE             in varchar2,                           -- Мнемокод типа события
    CPROPS                  in clob                                -- Свойства документа
  )
  is
    NCOMPANY                PKG_STD.TREF := GET_SESSION_COMPANY(); -- Рег. номер организации
    NDP_VER                 PKG_STD.TREF;                          -- Версия раздела "Свойства документов"
    RDOC                    PKG_XPATH.TDOCUMENT;                   -- Документ XML
    RNODE_ROOT              PKG_XPATH.TNODE;                       -- Корневой узел
    RNODE_PROPS             PKG_XPATH.TNODE;                       -- Узел "props"
    RNODE_PROP              PKG_XPATH.TNODE;                       -- Узел свойства (в формате "<SDP|NDP|DDP>_<РЕГ_НОМЕР>")
    SPROP_ID                PKG_STD.TSTRING;                       -- Код свойства документа из XML (в формате "<SDP|NDP|DDP>_<РЕГ_НОМЕР>")
    SPROP_CODE              PKG_STD.TSTRING;                       -- Мнемокод свойства документа
    SSTR_VALUE              PKG_STD.TSTRING := null;               -- Строковое значение
    NNUM_VALUE              PKG_STD.TLNUMBER := null;              -- Числовое значение
    DDATE_VALUE             PKG_STD.TLDATE := null;                -- Дата
  begin
    /* Считываем версию организации */
    FIND_VERSION_BY_COMPANY(NCOMPANY => NCOMPANY, SUNITCODE => SUNIT_DP, NVERSION => NDP_VER);
    /* Загрузка XML */
    RDOC := PKG_XPATH.PARSE_FROM_CLOB(LCXML => BLOB2CLOB(LBDATA   => BASE64_DECODE(LCSRCE => CPROPS),
                                                         SCHARSET => PKG_CHARSET.CHARSET_UTF_()));
    /* Разбор XML */
    RNODE_ROOT  := PKG_XPATH.ROOT_NODE(RDOCUMENT => RDOC);
    RNODE_PROPS := PKG_XPATH.SINGLE_NODE(RPARENT_NODE => RNODE_ROOT, SPATTERN => 'props');
    /* Если найдено событие */
    if (PKG_DOCS_PROPS_VALS.PROLOGUE(SUNITCODE => SUNIT_CLNEVENTS, NDOCUMENT => NCLNEVENTS)) then
      /* Цикл по свойствам документа типа события */
      for REC in (select CEP.RN,
                         CEP.PROPERTY,
                         DP.FORMAT,
                         DP.NUM_WIDTH,
                         DP.NUM_PRECISION,
                         DP.STR_WIDTH
                    from CLEVTPROPS  CEP,
                         CLNEVNTYPES CET,
                         DOCS_PROPS  DP
                   where CEP.PRN = CET.RN
                     and CET.EVNTYPE_CODE = SEVENT_TYPE
                     and CEP.COMPANY = NCOMPANY
                     and CEP.PROPERTY = DP.RN(+))
      loop
        /* Считываем код свойства */
        SPROP_ID     := UTL_DP_FORMATTED_ID_GET(NTYPE => REC.FORMAT, NRN => REC.PROPERTY);
        SPROP_CODE   := GET_DOCS_PROPS_CODE_ID(NFLAG_SMART => 0, NPROP_ID => REC.PROPERTY);
        /* Если в XML найдено новое значение свойства */
        if (PKG_XPATH.IS_NULL(RNODE => PKG_XPATH.SINGLE_NODE(RPARENT_NODE => RNODE_PROPS, SPATTERN => SPROP_ID)) =
           false) then
          /* Считываем узел свойства документа */
          RNODE_PROP := PKG_XPATH.SINGLE_NODE(RPARENT_NODE => RNODE_PROPS, SPATTERN => SPROP_ID);
          /* Исходим от типа свойства документа */
          case REC.FORMAT
            /* Строка */
            when 0 then
              SSTR_VALUE := PKG_XPATH.VALUE(RNODE => RNODE_PROP);
              /* Проверка длины строки */
              if (LENGTH(SSTR_VALUE) > REC.STR_WIDTH) then
                P_EXCEPTION(0,
                            'Недопустимый формат значения для свойства "%s" (ожидалась строка длиной "%s" символов).',
                            SPROP_CODE,
                            TO_CHAR(REC.STR_WIDTH));
              end if;
            /* Число */
            when 1 then
              NNUM_VALUE := PKG_XPATH.VALUE_NUM(RNODE => RNODE_PROP);
              /* Проверка длины и точности числа */
              if ((LENGTH(TO_CHAR(TRUNC(ABS(NNUM_VALUE)))) > (REC.NUM_WIDTH - REC.NUM_PRECISION)) or
                 (ROUND(NNUM_VALUE, REC.NUM_PRECISION) <> NNUM_VALUE)) then
                P_EXCEPTION(0,
                            'Недопустимый формат значения для свойства "%s" (ожидалось число размерностью "%s" с точностью "%s").',
                            SPROP_CODE,
                            TO_CHAR(REC.NUM_WIDTH),
                            TO_CHAR(REC.NUM_PRECISION));
              end if;
            /* Дата */
            when 2 then
              begin
                DDATE_VALUE := PKG_XPATH.VALUE_DATE(RNODE => RNODE_PROP);
              exception
                when others then
                  P_EXCEPTION(0, 'Недопустимый формат даты.');
              end;
            /* Время */
            else
              NNUM_VALUE := TO_DATE(PKG_XPATH.VALUE(RNODE => RNODE_PROP), 'HH24:MI:SS') -
                            TO_DATE('00:00:00', 'HH24:MI:SS');
          end case;
        end if;
        /* Добавление значения свойства */
        PKG_DOCS_PROPS_VALS.APPEND(SPROPERTY   => SPROP_CODE,
                                   SSTR_VALUE  => SSTR_VALUE,
                                   NNUM_VALUE  => NNUM_VALUE,
                                   DDATE_VALUE => DDATE_VALUE);
        /* Очищаем значения */
        SSTR_VALUE  := null;
        NNUM_VALUE  := null;
        DDATE_VALUE := null;
      end loop;
      PKG_DOCS_PROPS_VALS.EPILOGUE;
    end if;
  end CLNEVENTS_PROPS_INSERT;
  
  /* Добавление события */
  procedure CLNEVENTS_INSERT
  (
    SCRN                    in varchar2,                           -- Наименование каталога
    SPREF                   in varchar2,                           -- Префикс события
    SNUMB                   in varchar2,                           -- Номер события
    STYPE                   in varchar2,                           -- Тип события
    SSTATUS                 in varchar2,                           -- Статус события
    SPLAN_DATE              in varchar2,                           -- Дата планируемого начала работ
    SINIT_PERSON            in varchar2,                           -- Инициатор
    SCLIENT_CLIENT          in varchar2,                           -- Клиент-инициатор
    SCLIENT_PERSON          in varchar2,                           -- Сотрудник-инициатор
    SDESCRIPTION            in varchar2,                           -- Описание
    SREASON                 in varchar2,                           -- Причина
    CPROPS                  in clob                                -- Свойства документа
  )
  is
    NCOMPANY                PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса
    NCRN                    PKG_STD.TREF;                          -- Рег. номер каталога
    NCLNEVENTS              PKG_STD.TREF;                          -- Рег. номер события
  begin
    /* Считываем рег. номер каталога */
    FIND_ACATALOG_NAME(NFLAG_SMART => 0,
                       NCOMPANY    => NCOMPANY,
                       NVERSION    => null,
                       SUNITCODE   => SUNIT_CLNEVENTS,
                       SNAME       => SCRN,
                       NRN         => NCRN);
    /* Добавляем событие */
    P_CLNEVENTS_INSERT(NCOMPANY         => NCOMPANY,
                       NCRN             => NCRN,
                       SEVENT_PREF      => SPREF,
                       SEVENT_NUMB      => SNUMB,
                       SEVENT_TYPE      => STYPE,
                       SEVENT_STAT      => SSTATUS,
                       DPLAN_DATE       => TO_DATE(SPLAN_DATE, SDATE_PATTERN_HH_MI),
                       SINIT_PERSON     => SINIT_PERSON,
                       SCLIENT_CLIENT   => SCLIENT_CLIENT,
                       SCLIENT_PERSON   => SCLIENT_PERSON,
                       SSEND_CLIENT     => null,
                       SSEND_DIVISION   => null,
                       SSEND_POST       => null,
                       SSEND_PERFORM    => null,
                       SSEND_PERSON     => null,
                       SSEND_STAFFGRP   => null,
                       SSEND_USER_GROUP => null,
                       SSEND_USER_NAME  => null,
                       SEVENT_DESCR     => SDESCRIPTION,
                       SREASON          => SREASON,
                       NRN              => NCLNEVENTS);
    /* Добавляем значения свойств документа */
    CLNEVENTS_PROPS_INSERT(NCLNEVENTS => NCLNEVENTS, SEVENT_TYPE => STYPE, CPROPS => CPROPS);
  end CLNEVENTS_INSERT;
  
  /* Исправление события */
  procedure CLNEVENTS_UPDATE
  (
    NCLNEVENTS              in number,                             -- Рег. номер события
    SCLIENT_CLIENT          in varchar2,                           -- Клиент-инициатор
    SCLIENT_PERSON          in varchar2,                           -- Сотрудник-инициатор
    SDESCRIPTION            in varchar2,                           -- Описание
    CPROPS                  in clob                                -- Свойства
  )
  is
    NCOMPANY                PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса
    RCLNEVENTS              CLNEVENTS%rowtype;                     -- Запись события
    STYPE                   PKG_STD.TSTRING;                       -- Мнемокод типа события
    SSTATUS                 PKG_STD.TSTRING;                       -- Мнемокод статуса типа события
    SINIT_PERSON            PKG_STD.TSTRING;                       -- Мнемокод инициатора сотрудника
    SCLIENT_CLIENT_TMP      PKG_STD.TSTRING;                       -- Мнемокод клиента (организации) (не требуется)
    SCLIENT_PERSON_TMP      PKG_STD.TSTRING;                       -- Мнемокод клиента (сотрудника) (не требуется)
    SSEND_CLIENT            PKG_STD.TSTRING;                       -- Мнемокод направления (организация)
    SSEND_DIVISION          PKG_STD.TSTRING;                       -- Мнемокод направления (подразделение)
    SSEND_POST              PKG_STD.TSTRING;                       -- Мнемокод направления (должность)
    SSEND_PERFORM           PKG_STD.TSTRING;                       -- Мнемокод направления (должность в подразделении)
    SSEND_PERSON            PKG_STD.TSTRING;                       -- Мнемокод направления (сотрудник)
    SSEND_STAFFGRP          PKG_STD.TSTRING;                       -- Мнемокод направления (нештатная структура)
    SSEND_USER_GROUP        PKG_STD.TSTRING;                       -- Мнемокод направления (группа пользователей)
    SSEND_USER_NAME         PKG_STD.TSTRING;                       -- Мнемокод направления (группа пользователь)
    NBAN_UPDATE             PKG_STD.TNUMBER;                       -- Признак запрета исправления события в точке маршрута (0 - нет, 1 - да)
  begin
    /* Считываем запись события */
    RCLNEVENTS := UTL_CLNEVENTS_GET(NCOMPANY => NCOMPANY, NCLNEVENTS => NCLNEVENTS);
    /* Считываем мнемокоды связанных записей */
    UTL_CLNEVENTS_JOINS_GET(NCLNEVENTS       => RCLNEVENTS.RN,
                            STYPE            => STYPE,
                            SSTATUS          => SSTATUS,
                            SINIT_PERSON     => SINIT_PERSON,
                            SCLIENT_CLIENT   => SCLIENT_CLIENT_TMP,
                            SCLIENT_PERSON   => SCLIENT_PERSON_TMP,
                            SSEND_CLIENT     => SSEND_CLIENT,
                            SSEND_DIVISION   => SSEND_DIVISION,
                            SSEND_POST       => SSEND_POST,
                            SSEND_PERFORM    => SSEND_PERFORM,
                            SSEND_PERSON     => SSEND_PERSON,
                            SSEND_STAFFGRP   => SSEND_STAFFGRP,
                            SSEND_USER_GROUP => SSEND_USER_GROUP,
                            SSEND_USER_NAME  => SSEND_USER_NAME);
    /* Проверка возможности редактирования события в текущем статусе */
    NBAN_UPDATE := UTL_CLNEVENTS_BAN_UPDATE_GET(NCOMPANY => NCOMPANY, NCLNEVENTS => NCLNEVENTS);
    /* Если редактирование запрещено */
    if (NBAN_UPDATE = 1) then
      /* Формируем исключение */
      P_EXCEPTION(0, 'События в статусе "%s" запрещено редактировать.', SSTATUS);
    end if;
    /* Исправляем событие */
    P_CLNEVENTS_UPDATE(NCOMPANY         => NCOMPANY,
                       NRN              => NCLNEVENTS,
                       NREMOTE_ACCESS   => null,
                       SCHANGE_DATE     => STAMP2S(RCLNEVENTS.CHANGE_DATE),
                       SEVENT_TYPE      => STYPE,
                       SEVENT_STAT      => SSTATUS,
                       SCLIENT_CLIENT   => SCLIENT_CLIENT,
                       SCLIENT_PERSON   => SCLIENT_PERSON,
                       SSEND_CLIENT     => SSEND_CLIENT,
                       SSEND_DIVISION   => SSEND_DIVISION,
                       SSEND_POST       => SSEND_POST,
                       SSEND_PERFORM    => SSEND_PERFORM,
                       SSEND_PERSON     => SSEND_PERSON,
                       SSEND_STAFFGRP   => SSEND_STAFFGRP,
                       SSEND_USER_GROUP => SSEND_USER_GROUP,
                       SSEND_USER_NAME  => SSEND_USER_NAME,
                       SEVENT_DESCR     => SDESCRIPTION);
    /* Обновляем значения свойств документа */
    CLNEVENTS_PROPS_INSERT(NCLNEVENTS => NCLNEVENTS, SEVENT_TYPE => STYPE, CPROPS => CPROPS);
  end CLNEVENTS_UPDATE;
  
  /* Удаление события */
  procedure CLNEVENTS_DELETE
  (
    NCLNEVENTS              in number                              -- Рег. номер события
  )
  is
    NCOMPANY                PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса
  begin
    /* Удаляем событие */
    P_CLNEVENTS_DELETE(NCOMPANY => NCOMPANY, NRN => NCLNEVENTS);
    /* Удаляем значения свойств документа */
    PKG_DOCS_PROPS_VALS.AFTER_DELETE(SUNITCODE => SUNIT_CLNEVENTS, NDOCUMENT => NCLNEVENTS);
  end CLNEVENTS_DELETE;
  
  /* Изменение статуса события */
  procedure CLNEVENTS_STATE_CHANGE
  (
    NIDENT                  in out number,                         -- Рег. номер отмеченных записей
    NSTEP                   in out number,                         -- Шаг выполнения (0-прекратить выполнение, 1,2..- номер шага)
    NEVENT                  in out number,                         -- Событие, для отбора исполнителей
    SEVENT_TYPE             in out varchar2,                       -- Тип события, для отбора точек перехода и исполнителей
    SEVENT_STAT             in out varchar2,                       -- Cтатус события, текущий - для отбора точек перехода, следующий - для отбора исполнителей
    SINIT_PERSON            in out varchar2,                       -- Инициатор–сотрудник, для отбора исполнителей
    SINIT_AUTHNAME          in out varchar2,                       -- Инициатор–пользователь, для отбора исполнителей
    SCLIENT_CLIENT          in out varchar2,                       -- Клиент–организация, для отбора исполнителей
    SCLIENT_PERSON          in out varchar2,                       -- Клиент–сотрудник, для отбора исполнителей
    NPOINT                  in out number,                         -- Текущая точка маршрута
    NPASS                   in out number,                         -- Точка перехода
    NSELECT_EXEC            out number,                            -- Признак необходимости выбора исполнителя
    SEXECUTEMETHOD          out varchar2,                          -- Мнемокод метода
    SSEND_CLIENT            in varchar2,                           -- Направить – организация
    SSEND_DIVISION          in varchar2,                           -- Направить – подразделение
    SSEND_POST              in varchar2,                           -- Направить – должность
    SSEND_PERFORM           in varchar2,                           -- Направить – должность в подразделении
    SSEND_PERSON            in varchar2,                           -- Направить – сотрудник
    SSEND_STAFFGRP          in varchar2,                           -- Направить – нештатная структура
    SSEND_USER_GROUP        in varchar2,                           -- Направить – группа пользователей
    SSEND_USER_NAME         in varchar2,                           -- Направить – пользователь
    NSEND_PREDEFINED_EXEC   in number,                             -- Переадресация
    NSEND_PREDEFINED_PROC   in number,                             -- Процедура выбора предопределенного исполнителя
    SNEXT_STAT              in varchar2 := null,                   -- Следующий статус (при переносе события)
    SNOTE_HEADER            in varchar2 := null,                   -- Заголовок примечания (при наличии)
    SNOTE                   in varchar2 := null                    -- Примечание (при наличии)
  )
  is
    NCOMPANY                PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса
    SEVENT                  PKG_STD.TSTRING;                       -- Полный номер события
    NCONFIRM_REQUIRED       PKG_STD.TNUMBER;                       -- Флаг необходимости подтверждения перехода
    SCONFIRM_TEXT           PKG_STD.TSTRING;                       -- Текст подтверждения перехода
    NTMP                    PKG_STD.TREF;                          -- Заглушка
    NSTEP_CURRENT           PKG_STD.TREF;                          -- Номер текущего шага
    NNOTE_RN                PKG_STD.TREF;                          -- Рег. номер добавленного примечания
    
    /* Считывание рег. номер точки маршрута */
    function EVRTPTPASS_NEXT_GET
    (
      NCOMPANY              in number,    -- Рег. номер организации
      SEVENT_TYPE           in varchar2,  -- Мнемокод типа события
      NPOINT                in number,    -- Рег. номер текущей точки
      SEVENT_STAT           in varchar2,  -- Мнемокод текущего статуса события
      SNEXT_STAT            in varchar2   -- Мнемокод следующего статуса события
    ) return                number        -- Рег. номер точки перехода
    is
      NNEXT_POINT           PKG_STD.TREF; -- Рег. номер следующей точки
      NRESULT               PKG_STD.TREF; -- Рег. номер точки перехода
    begin
      /* Определение следующей точки маршрута */
      FIND_EVRPOINTS_BY_STATUS(NFLAG_SMART   => 0,
                               NFLAG_OPTION  => 0,
                               NCOMPANY      => NCOMPANY,
                               SEVENT_TYPE   => SEVENT_TYPE,
                               SEVENT_STATUS => SNEXT_STAT,
                               NRN           => NNEXT_POINT);
      /* Считывание рег. номера точки перехода */
      begin
        select T.RN
          into NRESULT
          from EVRTPTPASS T
         where T.PRN = NPOINT
           and T.NEXT_POINT = NNEXT_POINT;
      exception
        when others then
          P_EXCEPTION(0,
                      'Ошибка считывания точки перехода из статуса "%s" в статус "%s".',
                      SEVENT_STAT,
                      SNEXT_STAT);
      end;
      /* Возвращаем результат */
      return NRESULT;
    end EVRTPTPASS_NEXT_GET;
  begin
    /* Определяем номер текущего шага */
    NSTEP_CURRENT := NSTEP;
    /* Если это первый шаг */
    if (NSTEP_CURRENT = 1) then
      /* Генерируем идентификатор отмеченных записей */
      NIDENT := GEN_IDENT();
      /* Добавляем запись события в отмеченные */
      P_SELECTLIST_BASE_INSERT(NIDENT       => NIDENT,
                               NCOMPANY     => NCOMPANY,
                               NDOCUMENT    => NEVENT,
                               SUNITCODE    => SUNIT_CLNEVENTS,
                               SACTIONCODE  => SSELECTLIST_ACTION,
                               NCRN         => null,
                               NDOCUMENT1   => null,
                               SUNITCODE1   => null,
                               SACTIONCODE1 => null,
                               NRN          => NTMP);
    end if;
    /* Изменяем статус события */
    P_CLNEVENTS_CHANGE_STATE_WEB(NCOMPANY              => NCOMPANY,
                                 NIDENT                => NIDENT,
                                 NSTEP                 => NSTEP,
                                 NEVENT                => NEVENT,
                                 SEVENT                => SEVENT,
                                 SEVENT_TYPE           => SEVENT_TYPE,
                                 SEVENT_STAT           => SEVENT_STAT,
                                 SINIT_PERSON          => SINIT_PERSON,
                                 SINIT_AUTHNAME        => SINIT_AUTHNAME,
                                 SCLIENT_CLIENT        => SCLIENT_CLIENT,
                                 SCLIENT_PERSON        => SCLIENT_PERSON,
                                 NPOINT                => NPOINT,
                                 NPASS                 => NPASS,
                                 NSELECT_EXEC          => NSELECT_EXEC,
                                 NCONFIRM_REQUIRED     => NCONFIRM_REQUIRED,
                                 SCONFIRM_TEXT         => SCONFIRM_TEXT,
                                 SEXECUTEMETHOD        => SEXECUTEMETHOD,
                                 SSEND_CLIENT          => SSEND_CLIENT,
                                 SSEND_DIVISION        => SSEND_DIVISION,
                                 SSEND_POST            => SSEND_POST,
                                 SSEND_PERFORM         => SSEND_PERFORM,
                                 SSEND_PERSON          => SSEND_PERSON,
                                 SSEND_STAFFGRP        => SSEND_STAFFGRP,
                                 SSEND_USER_GROUP      => SSEND_USER_GROUP,
                                 SSEND_USER_NAME       => SSEND_USER_NAME,
                                 NSEND_PREDEFINED_EXEC => NSEND_PREDEFINED_EXEC,
                                 NSEND_PREDEFINED_PROC => NSEND_PREDEFINED_PROC);
    /* Если это первый шаг и уже известен следующий статус */
    if ((NSTEP_CURRENT = 1) and (SNEXT_STAT is not null)) then
      /* Определим точку перехода */
      NPASS := EVRTPTPASS_NEXT_GET(NCOMPANY    => NCOMPANY,
                                   SEVENT_TYPE => SEVENT_TYPE,
                                   NPOINT      => NPOINT,
                                   SEVENT_STAT => SEVENT_STAT,
                                   SNEXT_STAT  => SNEXT_STAT);
      /* Указываем следующий статус */
      SEVENT_STAT := SNEXT_STAT;
    end if;
    /* Если это последний шаг */
    if (NSTEP_CURRENT = 4) then
      /* Если добавлено примечание */
      if (SNOTE is not null) then
        P_CLNEVNOTES_INSERT(NCOMPANY     => NCOMPANY,
                            NPRN         => NEVENT,
                            SNOTE_HEADER => SNOTE_HEADER,
                            SNOTE        => SNOTE,
                            NRN          => NNOTE_RN);
      end if;
      /* Очищаем отмеченные записи */
      P_SELECTLIST_CLEAR(NIDENT => NIDENT);
    end if;
  exception
    when others then
      /* Если список отмеченных есть */
      if (NIDENT is not null) then
        /* Удаляем в автономной транзакции */
        P_SELECTLIST_CLEAR_AT(NIDENT => NIDENT);
      end if;
      /* Вернем ошибку */
      PKG_STATE.DIAGNOSTICS_STACKED();
      P_EXCEPTION(0, PKG_STATE.SQL_ERRM());
  end CLNEVENTS_STATE_CHANGE;
  
  /* Перемещение события */
  procedure CLNEVENTS_MOVE
  (
    NCLNEVENTS              in number,  -- Рег. номер события
    NCRN                    in number   -- Рег. номер каталога-получателя
  )
  is
  begin
    /* Перемещение события в другой каталог */
    P_DOCUMENT_MOVE(SUNITCODE => 'ClientEvents', NDOCUMENT => NCLNEVENTS, NTARGET => NCRN);
  end CLNEVENTS_MOVE;
  
  /* Переадресация события */
  procedure CLNEVENTS_SEND
  (
    NIDENT                  in out number,                         -- Рег. номер отмеченных записей
    NSTEP                   in out number,                         -- Шаг выполнения
    NEVENT                  in out number,                         -- Событие, для отбора исполнителей
    SEVENT_TYPE             in out varchar2,                       -- Тип события, для отбора точек перехода и исполнителей
    SEVENT_STAT             in out varchar2,                       -- Текущий статус события, для отбора исполнителей
    SINIT_PERSON            in out varchar2,                       -- Инициатор–сотрудник, для отбора исполнителей
    SINIT_AUTHNAME          in out varchar2,                       -- Инициатор–пользователь, для отбора исполнителей
    SCLIENT_CLIENT          in out varchar2,                       -- Клиент–организация, для отбора исполнителей
    SCLIENT_PERSON          in out varchar2,                       -- Клиент–сотрудник, для отбора исполнителей
    SEXECUTEMETHOD          out varchar2,                          -- Мнемокод метода
    SSEND_CLIENT            in varchar2,                           -- Направить – организация
    SSEND_DIVISION          in varchar2,                           -- Направить – подразделение
    SSEND_POST              in varchar2,                           -- Направить – должность
    SSEND_PERFORM           in varchar2,                           -- Направить – должность в подразделении
    SSEND_PERSON            in out varchar2,                       -- Направить – сотрудник
    SSEND_STAFFGRP          in varchar2,                           -- Направить – нештатная структура
    SSEND_USER_GROUP        in varchar2,                           -- Направить – группа пользователей
    SSEND_USER_NAME         in out varchar2,                       -- Направить – пользователь
    NSEND_PREDEFINED_EXEC   in number,                             -- Переадресация
    NSEND_PREDEFINED_PROC   in number,                             -- Процедура выбора предопределенного исполнителя
    SNOTE_HEADER            in varchar2 := null,                   -- Заголовок примечания (при наличии)
    SNOTE                   in varchar2 := null                    -- Примечание (при наличии)
  )
  is
    NCOMPANY                PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса
    NTMP                    PKG_STD.TREF;                          -- Заглушка
    NSTEP_CURRENT           PKG_STD.TREF;                          -- Номер текущего шага
    NNOTE_RN                PKG_STD.TREF;                          -- Рег. номер добавленного примечания
  begin
    /* Определяем номер текущего шага */
    NSTEP_CURRENT := NSTEP;
    /* Если это первый шаг */
    if (NSTEP_CURRENT = 1) then
      /* Генерируем идентификатор отмеченных записей */
      NIDENT := GEN_IDENT();
      /* Добавляем запись события в отмеченные */
      P_SELECTLIST_BASE_INSERT(NIDENT       => NIDENT,
                               NCOMPANY     => NCOMPANY,
                               NDOCUMENT    => NEVENT,
                               SUNITCODE    => SUNIT_CLNEVENTS,
                               SACTIONCODE  => SSELECTLIST_ACTION,
                               NCRN         => null,
                               NDOCUMENT1   => null,
                               SUNITCODE1   => null,
                               SACTIONCODE1 => null,
                               NRN          => NTMP);
    end if;
    /* Выполняем переадресацию события */
    P_CLNEVENTS_SEND_WEB(NCOMPANY              => NCOMPANY,
                         NIDENT                => NIDENT,
                         NSTEP                 => NSTEP,
                         NEVENT                => NEVENT,
                         SEVENT_TYPE           => SEVENT_TYPE,
                         SEVENT_STAT           => SEVENT_STAT,
                         SINIT_PERSON          => SINIT_PERSON,
                         SINIT_AUTHNAME        => SINIT_AUTHNAME,
                         SCLIENT_CLIENT        => SCLIENT_CLIENT,
                         SCLIENT_PERSON        => SCLIENT_PERSON,
                         SEXECUTEMETHOD        => SEXECUTEMETHOD,
                         SSEND_CLIENT          => SSEND_CLIENT,
                         SSEND_DIVISION        => SSEND_DIVISION,
                         SSEND_POST            => SSEND_POST,
                         SSEND_PERFORM         => SSEND_PERFORM,
                         SSEND_PERSON          => SSEND_PERSON,
                         SSEND_STAFFGRP        => SSEND_STAFFGRP,
                         SSEND_USER_GROUP      => SSEND_USER_GROUP,
                         SSEND_USER_NAME       => SSEND_USER_NAME,
                         NSEND_PREDEFINED_EXEC => NSEND_PREDEFINED_EXEC,
                         NSEND_PREDEFINED_PROC => NSEND_PREDEFINED_PROC);
    /* Если это последний шаг */
    if (NSTEP_CURRENT = 2) then
      /* Если добавлено примечание */
      if (SNOTE is not null) then
        P_CLNEVNOTES_INSERT(NCOMPANY     => NCOMPANY,
                            NPRN         => NEVENT,
                            SNOTE_HEADER => SNOTE_HEADER,
                            SNOTE        => SNOTE,
                            NRN          => NNOTE_RN);
      end if;
      /* Очищаем отмеченные записи */
      P_SELECTLIST_CLEAR(NIDENT => NIDENT);
    end if;
  exception
    when others then
      /* Если список отмеченных есть */
      if (NIDENT is not null) then
        /* Удаляем в автономной транзакции */
        P_SELECTLIST_CLEAR_AT(NIDENT => NIDENT);
      end if;
      /* Вернем ошибку */
      PKG_STATE.DIAGNOSTICS_STACKED();
      P_EXCEPTION(0, PKG_STATE.SQL_ERRM());
  end CLNEVENTS_SEND;
  
  /* Возврат в предыдущую точку события */
  procedure CLNEVENTS_RETURN
  (
    NCLNEVENTS              in number                              -- Рег. номер события
  )
  is
    NCOMPANY                PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса
  begin
    /* Возвращаем событие */
    P_CLNEVENTS_RETURN_WEB(NCOMPANY => NCOMPANY, NIDENT => null, NEVENT => NCLNEVENTS);
  end CLNEVENTS_RETURN;
  
  /* Считывание маршрутов и исполнителей события */
  procedure CLNEVENTS_GET_INFO_BY_CODE
  (
    SEVNTYPE_CODE           in varchar2,                           -- Мнемокод типа события
    COUT                    out clob                               -- XML с параметрами фильтра по умолчанию
  )
  is
    NCOMPANY                PKG_STD.TREF := GET_SESSION_COMPANY(); -- Рег. номер организации
    SSRC                    PKG_STD.TSTRING;                       -- Наименование точки маршрута
    SDEST                   PKG_STD.TSTRING;                       -- Наименование точки перехода
  begin
    /* Формируем XML */
    PKG_XFAST.PROLOGUE(ITYPE => PKG_XFAST.CONTENT_);
    PKG_XFAST.DOWN_NODE(SNAME => 'DATA');
    /* Цикл по точкам маршрута и точкам перехода */
    for REC in (select CST1.EVNSTAT_CODE SSRC,
                       CST2.EVNSTAT_CODE SDEST
                  from EVRTPTPASS   EPS,
                       EVRTPOINTS   EP1,
                       CLNEVNTYPSTS CT1,
                       CLNEVNSTATS  CST1,
                       EVRTPOINTS   EP2,
                       CLNEVNTYPSTS CT2,
                       CLNEVNSTATS  CST2
                 where EPS.PRN in (select EP.RN
                                     from EVROUTES    ER,
                                          CLNEVNTYPES C,
                                          EVRTPOINTS  EP
                                    where ER.COMPANY = NCOMPANY
                                      and ER.EVENT_TYPE = C.RN
                                      and C.EVNTYPE_CODE = SEVNTYPE_CODE
                                      and EP.PRN = ER.RN)
                   and EPS.FORCE_ONLY = 0
                   and EPS.PRN = EP1.RN
                   and EP1.EVENT_STATUS = CT1.RN
                   and CT1.EVENT_STATUS = CST1.RN
                   and EPS.NEXT_POINT = EP2.RN
                   and EP2.EVENT_STATUS = CT2.RN
                   and CT2.EVENT_STATUS = CST2.RN)
    loop
      /* Добавляем информацию о маршруте */
      PKG_XFAST.DOWN_NODE(SNAME => 'XEVROUTES');
      /* Начало перехода */
      PKG_XFAST.DOWN_NODE(SNAME => 'SSOURCE');
      PKG_XFAST.VALUE(SVALUE => REC.SSRC);
      PKG_XFAST.UP();
      /* Конец перехода */
      PKG_XFAST.DOWN_NODE(SNAME => 'SDESTINATION');
      PKG_XFAST.VALUE(SVALUE => REC.SDEST);
      PKG_XFAST.UP();
      PKG_XFAST.UP();
    end loop;
    /* Цикл по точкам маршрута */
    for REC in (select CST.EVNSTAT_CODE,
                       CST.EVNSTAT_NAME,
                       EP.COMMENTARY,
                       EP.ADDNOTE_ONCHST,
                       EP.ADDNOTE_ONSEND,
                       EP.BAN_UPDATE
                  from EVROUTES     ER,
                       CLNEVNTYPES  C,
                       EVRTPOINTS   EP,
                       CLNEVNTYPSTS CT,
                       CLNEVNSTATS  CST
                 where ER.COMPANY = NCOMPANY
                   and ER.EVENT_TYPE = C.RN
                   and C.EVNTYPE_CODE = SEVNTYPE_CODE
                   and EP.PRN = ER.RN
                   and EP.EVENT_STATUS = CT.RN
                   and CT.EVENT_STATUS = CST.RN)
    loop
      /* Добавляем информацию о точке маршрута */
      PKG_XFAST.DOWN_NODE(SNAME => 'XEVPOINTS');
      /* Мнемокод точки маршрута */
      PKG_XFAST.DOWN_NODE(SNAME => 'SEVPOINT');
      PKG_XFAST.VALUE(SVALUE => REC.EVNSTAT_CODE);
      PKG_XFAST.UP();
      /* Описание в точке маршрута */
      PKG_XFAST.DOWN_NODE(SNAME => 'SEVPOINT_DESCR');
      PKG_XFAST.VALUE(SVALUE => COALESCE(REC.COMMENTARY, REC.EVNSTAT_NAME));
      PKG_XFAST.UP();
      /* Признак добавления примечания при переходе в точку маршрута */
      PKG_XFAST.DOWN_NODE(SNAME => 'ADDNOTE_ONCHST');
      PKG_XFAST.VALUE(BVALUE => INT2BOOL(REC.ADDNOTE_ONCHST));
      PKG_XFAST.UP();
      /* Признак добавления примечания при перенаправлении в точке маршрута */
      PKG_XFAST.DOWN_NODE(SNAME => 'ADDNOTE_ONSEND');
      PKG_XFAST.VALUE(BVALUE => INT2BOOL(REC.ADDNOTE_ONSEND));
      PKG_XFAST.UP();
      /* Признак запрета исправления события в точке маршрута */
      PKG_XFAST.DOWN_NODE(SNAME => 'BAN_UPDATE');
      PKG_XFAST.VALUE(BVALUE => INT2BOOL(REC.BAN_UPDATE));
      PKG_XFAST.UP();
      PKG_XFAST.UP();
    end loop;
    /* Цикл по типам заголовков примечаний */
    for REC in (select NT.NAME
                  from CLNEVNTYPES      ET,
                       CLNEVNTYPENOTES  TN,
                       CLNEVNTNOTETYPES NT
                 where ET.COMPANY = NCOMPANY
                   and ET.EVNTYPE_CODE = SEVNTYPE_CODE
                   and TN.PRN = ET.RN
                   and NT.RN = TN.NOTE_TYPE)
    loop
      /* Добавляем информацию о заголовке примечания */
      PKG_XFAST.DOWN_NODE(SNAME => 'XNOTETYPES');
      /* Наименование типа заголовка примечания */
      PKG_XFAST.DOWN_NODE(SNAME => 'SNAME');
      PKG_XFAST.VALUE(SVALUE => REC.NAME);
      PKG_XFAST.UP();
      PKG_XFAST.UP();
    end loop;
    PKG_XFAST.UP();
    /* Сериализуем в CLOB */
    COUT := PKG_XFAST.SERIALIZE_TO_CLOB();
    PKG_XFAST.EPILOGUE();
  end CLNEVENTS_GET_INFO_BY_CODE;
  
  /* Считывание учётных документов события */
  procedure CLNEVENTS_DOCLINKS_GET
  (
    SEVNTYPE_CODE           in varchar2,                           -- Мнемокод типа события
    COUT                    out clob                               -- XML с параметрами фильтра по умолчанию
  )
  is
    NCOMPANY                PKG_STD.TREF := GET_SESSION_COMPANY(); -- Рег. номер организации
  begin
    /* Формируем XML */
    PKG_XFAST.PROLOGUE(ITYPE => PKG_XFAST.CONTENT_);
    PKG_XFAST.DOWN_NODE(SNAME => 'DATA');
    /* Цикл по учётным документам */
    for REC in (select C.LINKED_RN   NRN,
                       C.LINKED_UNIT SUNIT
                  from CLNEVENTS   C,
                       CLNEVNTYPES CT
                 where C.COMPANY = NCOMPANY
                   and C.EVENT_TYPE = CT.RN
                   and CT.EVNTYPE_CODE = SEVNTYPE_CODE
                   and C.LINKED_RN is not null)
    loop
      PKG_XFAST.DOWN_NODE(SNAME => 'XDOCLINKS');
      /* Идентификатор */
      PKG_XFAST.DOWN_NODE(SNAME => 'NRN');
      PKG_XFAST.VALUE(NVALUE => REC.NRN);
      PKG_XFAST.UP();
      /* Описатель документа */
      PKG_XFAST.DOWN_NODE(SNAME => 'SDESCR');
      PKG_XFAST.VALUE(SVALUE => UTL_UNITLIST_DESCR_GET(SUNIT_CODE => REC.SUNIT, NDOCUMENT => REC.NRN));
      PKG_XFAST.UP();
      PKG_XFAST.UP();
    end loop;
    PKG_XFAST.UP();
    /* Сериализуем в CLOB */
    COUT := PKG_XFAST.SERIALIZE_TO_CLOB();
    PKG_XFAST.EPILOGUE();
  end CLNEVENTS_DOCLINKS_GET;
  
  /* Считывание списка рег. номеров дочерних каталогов (включая основной) */
  procedure CLNEVENTS_SUBCATALOGS_GET
  (
    SCRN_NAME               in varchar2,                           -- Наименование каталога
    NSUBCAT                 in number := 0,                        -- Признак включения подкаталогов (0 - нет, 1 - да)
    SRESULT                 out varchar2                           -- Список рег. номеров каталогов
  )
  is
    NCOMPANY                PKG_STD.TREF := GET_SESSION_COMPANY(); -- Рег. номер организации
    NCRN_MAIN               PKG_STD.TREF;                          -- Рег. номер основного каталога
  begin
    /* Считываем рег. номер основого каталога */
    FIND_ACATALOG_NAME(NFLAG_SMART => 0,
                       NCOMPANY    => NCOMPANY,
                       NVERSION    => null,
                       SUNITCODE   => SUNIT_CLNEVENTS,
                       SNAME       => SCRN_NAME,
                       NRN         => NCRN_MAIN);
    /* Если требуется включить подкаталоги */
    if (NSUBCAT = 1) then
      /* Цикл по иерерахии каталогов */
      for REC in (select A.RN from ACATALOG A start with A.RN = NCRN_MAIN connect by prior A.RN = A.CRN)
      loop
        SRESULT := SRESULT || REC.RN || ';';
      end loop;
    else
      /* Указываем только основной каталог */
      SRESULT := TO_CHAR(NCRN_MAIN);
    end if;
    /* Удаляем лишний ";" */
    SRESULT := RTRIM(SRESULT, ';');
  end CLNEVENTS_SUBCATALOGS_GET;
  
  /* Формирование условий отбора фильтра */
  procedure CLNEVENTS_COND
  is
  begin
    /* Установка главной таблицы */
    PKG_COND_BROKER.SET_TABLE(STABLE_NAME => 'CLNEVENTS');
    /* Формирование условий отбора */
    /* Условие по состоянию события */
    PKG_COND_BROKER.ADD_CONDITION_BETWEEN(SCOLUMN_NAME         => 'CLOSED',
                                          SCONDITION_NAME_FROM => 'BYEV_CLOSED_From',
                                          SCONDITION_NAME_TO   => 'BYEV_CLOSED_To');
    /* Условие по типу события */
    PKG_COND_BROKER.ADD_CONDITION_CODE(SCOLUMN_NAME    => 'EVNTYPE_CODE',
                                       SCONDITION_NAME => 'BYEV_TYPE',
                                       SJOINS          => 'EVENT_TYPE <- RN;CLNEVNTYPES');
    /* Условие по каталогу события */
    PKG_COND_BROKER.ADD_CONDITION_ENUM(SCOLUMN_NAME => 'CRN', SCONDITION_NAME => 'BYEV_CRN');
    /* Условие по исполнителю */
    PKG_COND_BROKER.ADD_CONDITION_CODE(SCOLUMN_NAME    => 'AGNABBR',
                                       SCONDITION_NAME => 'BYEV_S_PERSON',
                                       SJOINS          => 'SEND_PERSON <- RN;CLNPERSONS;PERS_AGENT <- RN;AGNLIST');
    /* Условие по подразделению */
    PKG_COND_BROKER.ADD_CONDITION_CODE(SCOLUMN_NAME    => 'CODE',
                                       SCONDITION_NAME => 'BYEV_S_DIVISION',
                                       SJOINS          => 'SEND_DIVISION <- RN;INS_DEPARTMENT');
    /* Условие по группе пользователей */
    PKG_COND_BROKER.ADD_CONDITION_CODE(SCOLUMN_NAME    => 'CODE',
                                       SCONDITION_NAME => 'BYEV_S_USER_GROUP',
                                       SJOINS          => 'SEND_USER_GROUP <- RN;USERGRP');
    /* Условие по учётному документу */
    PKG_COND_BROKER.ADD_CONDITION_COMPARE(SCOLUMN_NAME    => 'LINKED_RN',
                                          SOPERATION      => '=',
                                          SCONDITION_NAME => 'BYEV_LINKED_RN');
  end CLNEVENTS_COND;
  
  /* Считывание настройки раздела "События" для пользователя */
  procedure CLNEVENTS_DP_RULES_GET
  (
    COUT                    out clob                                          -- XML с настройкой раздела
  )
  is
    SAUTHID                 PKG_STD.TSTRING := PKG_SESSION.GET_UTILIZER();    -- Пользователь
    NCOMPANY                PKG_STD.TREF := GET_SESSION_COMPANY();            -- Рег. номер организации
    SAPPCODE                PKG_STD.TSTRING := PKG_SESSION.GET_APPLICATION(); -- Код приложения сеанса
    BXML                    blob;                                             -- XML профиля пользователя для раздела "События"
    RDOC                    PKG_XPATH.TDOCUMENT;                              -- Документ XML
    RNODE_ROOT              PKG_XPATH.TNODE;                                  -- Корневой узел
    RNODE_MAIN              PKG_XPATH.TNODE;                                  -- Основной узел
    RNODE_GRIDFRAME         PKG_XPATH.TNODE;                                  -- Узел "gridFrame"
    RNODE_DECOR_RULES       PKG_XPATH.TNODE;                                  -- Узел "decorationRules"
    RNODE_RULE              PKG_XPATH.TNODE;                                  -- Узел "rule"
    RNODE_RULE_LIST         PKG_XPATH.TNODES;                                 -- Список узлов "rule"
    SFIELD                  PKG_STD.TSTRING;                                  -- Код свойства документа (в формате "DP_<РЕГ_НОМЕР>")
    SCOLOR                  PKG_STD.TSTRING;                                  -- Код цвета
    SDATA_TYPE              PKG_STD.TSTRING;                                  -- Тип данных
    SDP_NAME                PKG_STD.TSTRING;                                  -- Наименование свойства документа
    NFROM_VALUE             PKG_STD.TNUMBER;                                  -- Значение с (number)
    NTO_VALUE               PKG_STD.TNUMBER;                                  -- Значение по (number)
    SFROM_VALUE             PKG_STD.TSTRING;                                  -- Значение с (string)
    STO_VALUE               PKG_STD.TSTRING;                                  -- Значение по (string)
    
    /* Считывание наименования свойства документа */
    function DOCS_PROPS_NAME_GET
    (
      SFIELD                in varchar2      -- Код свойства документа (в формате "DP_<РЕГ_НОМЕР>")
    ) return                varchar2         -- Наименование свойства документа
    is
      NRN                   PKG_STD.TREF;    -- Рег. номер свойства документа
      SRESULT               PKG_STD.TSTRING; -- Наименование доп. свойства
    begin
      /* Если переданный код свойства соответствует формату */
      if (INSTR(SFIELD, 'DP_') <> 0) then      
        /* Определяем рег. номер свойства документа по формату "DP_<РЕГ_НОМЕР>" */
        NRN := TO_NUMBER(SUBSTR(SFIELD, INSTR(SFIELD, '_') + 1));
        /* Считываем наименование из записи свойства документа */
        begin
          select T.NAME into SRESULT from DOCS_PROPS T where T.RN = NRN;
        exception
          when NO_DATA_FOUND then
            P_EXCEPTION(0,
                        'Ошибка считывания записи свойства документа с рег. номером (%s).');
          when others then
            P_EXCEPTION(0,
                        'Ошибка считывания наименования свойства документа с рег. номером (%s).');
        end;
      end if;
      /* Возвращаем результат */
      return SRESULT;
    end DOCS_PROPS_NAME_GET;
    
    /* Считывание профиля пользователя для раздела "События" */
    function USERPROFILES_GET
    (
      NCOMPANY              in number,   -- Рег. номер организации
      SAPPCODE              in varchar2, -- Код приложения
      SAUTHID               in varchar2  -- Мнемокод пользователя
    ) return                blob         -- Профиль пользователя для раздела "События"
    is
      BRESULT               blob;        -- Профиль пользователя для раздела "События"
    begin
      /* Считываем профиль пользователя для раздела "События" */
      begin
        select U.USERDATA
          into BRESULT
          from USERPROFILES U
         where U.COMPANY = NCOMPANY
           and U.AUTHID = SAUTHID
           and U.REC_TYPE = 1
           and U.UNITMODE = 0
           and U.UNITCODE = SUNIT_CLNEVENTS
           and U.KIND = 2           
           and U.UNITFUNC is null
           and U.REC_KEY is null
           and U.SHOW_METHOD = 'main'           
           and U.APPCODE = SAPPCODE;
      exception
        when others then
          return null;
      end;
      /* Возвращаем результат */
      return BRESULT;
    end USERPROFILES_GET;
  begin
    /* Считываем профиль пользователя для раздела "События" */
    BXML := USERPROFILES_GET(NCOMPANY => NCOMPANY, SAPPCODE => SAPPCODE, SAUTHID => SAUTHID);
    /* Проверим, что профиль не пустой */
    if (BXML is null) then
      return;
    end if;
    /* Данные в профиле есть - будем разбирать */
    begin
      /* Формируем XML данных */
      PKG_XFAST.PROLOGUE(ITYPE => PKG_XFAST.CONTENT_);
      PKG_XFAST.DOWN_NODE(SNAME => 'DATA');
      /* Загрузка XML */
      RDOC       := PKG_XPATH.PARSE_FROM_BLOB(LBXML => BXML);
      RNODE_ROOT := PKG_XPATH.ROOT_NODE(RDOCUMENT => RDOC);
      /* Обработка XML */
      RNODE_MAIN        := PKG_XPATH.FIRST_NODE(RPARENT_NODE => RNODE_ROOT);
      RNODE_GRIDFRAME   := PKG_XPATH.SINGLE_NODE(RPARENT_NODE => RNODE_MAIN, SPATTERN => 'gridFrame');
      RNODE_DECOR_RULES := PKG_XPATH.SINGLE_NODE(RPARENT_NODE => RNODE_GRIDFRAME, SPATTERN => 'decorationRules');
      RNODE_RULE_LIST   := PKG_XPATH.LIST_NODES(RPARENT_NODE => RNODE_DECOR_RULES, SPATTERN => 'rule');
      /* Цикл по узлам внутри узла rule */
      for I in 1 .. PKG_XPATH.COUNT_NODES(RNODES => RNODE_RULE_LIST)
      loop
        /* Считываем текущее правило */
        RNODE_RULE := PKG_XPATH.ITEM_NODE(RNODES => RNODE_RULE_LIST, INUMBER => I);
        /* Атрибуты */
        SFIELD     := PKG_XPATH.ATTRIBUTE(RNODE => RNODE_RULE, SNAME => 'field');
        SCOLOR     := PKG_XPATH.ATTRIBUTE(RNODE => RNODE_RULE, SNAME => 'color');
        SDATA_TYPE := PKG_XPATH.ATTRIBUTE(RNODE => RNODE_RULE, SNAME => 'dataType');
        /* Считываем наименование свойства документа */
        SDP_NAME := DOCS_PROPS_NAME_GET(SFIELD => SFIELD);
        /* Если это правило по доп. свойству и типа "строка" или "число" */
        if (SDP_NAME is not null) and (SDATA_TYPE in ('number', 'string')) then
          PKG_XFAST.DOWN_NODE(SNAME => 'XRULES');
          /* Код правила */
          PKG_XFAST.DOWN_NODE(SNAME => 'SFIELD');
          PKG_XFAST.VALUE(SVALUE => SFIELD);
          PKG_XFAST.UP();
          /* Наименование доп. свойства */
          PKG_XFAST.DOWN_NODE(SNAME => 'SDP_NAME');
          PKG_XFAST.VALUE(SVALUE => SDP_NAME);
          PKG_XFAST.UP();
          /* Код цвета */
          PKG_XFAST.DOWN_NODE(SNAME => 'SCOLOR');
          PKG_XFAST.VALUE(SVALUE => SCOLOR);
          PKG_XFAST.UP();
          /* Тип значения */
          PKG_XFAST.DOWN_NODE(SNAME => 'STYPE');
          PKG_XFAST.VALUE(SVALUE => SDATA_TYPE);
          PKG_XFAST.UP();
          /* Исходим от типа данных */
          case SDATA_TYPE
            /* Число */
            when 'number' then
              NFROM_VALUE := PKG_XPATH.VALUE_NUM(RNODE => PKG_XPATH.SINGLE_NODE(RPARENT_NODE => RNODE_RULE,
                                                                                SPATTERN     => 'fromValue'));
              NTO_VALUE   := PKG_XPATH.VALUE_NUM(RNODE => PKG_XPATH.SINGLE_NODE(RPARENT_NODE => RNODE_RULE,
                                                                                SPATTERN     => 'toValue'));
              /* Число с */
              PKG_XFAST.DOWN_NODE(SNAME => 'NFROM');
              PKG_XFAST.VALUE(NVALUE => NFROM_VALUE);
              PKG_XFAST.UP();
              /* Число по */
              PKG_XFAST.DOWN_NODE(SNAME => 'NTO');
              PKG_XFAST.VALUE(NVALUE => NTO_VALUE);
              PKG_XFAST.UP();
            /* Строка */
            when 'string' then
              SFROM_VALUE := PKG_XPATH.VALUE(RNODE => PKG_XPATH.SINGLE_NODE(RPARENT_NODE => RNODE_RULE,
                                                                            SPATTERN     => 'value'));
              STO_VALUE   := PKG_XPATH.VALUE(RNODE => PKG_XPATH.SINGLE_NODE(RPARENT_NODE => RNODE_RULE,
                                                                            SPATTERN     => 'value'));
              /* Строка с */
              PKG_XFAST.DOWN_NODE(SNAME => 'SFROM');
              PKG_XFAST.VALUE(SVALUE => SFROM_VALUE);
              PKG_XFAST.UP();
              /* Строка по */
              PKG_XFAST.DOWN_NODE(SNAME => 'STO');
              PKG_XFAST.VALUE(SVALUE => STO_VALUE);
              PKG_XFAST.UP();
          end case;
          PKG_XFAST.UP();
        end if;
      end loop;
      PKG_XPATH.FREE(RDOCUMENT => RDOC);
      PKG_XFAST.UP();
      /* Сериализуем в CLOB */
      COUT := PKG_XFAST.SERIALIZE_TO_CLOB();
      PKG_XFAST.EPILOGUE();
    exception
      when others then
        PKG_XPATH.FREE(RDOCUMENT => RDOC);
        PKG_XFAST.EPILOGUE();
    end;
  end CLNEVENTS_DP_RULES_GET;
  
  /* Считывание свойств раздела "События" */
  procedure CLNEVENTS_PROPS_GET
  (
    SEVNTYPE_CODE           in varchar2,                           -- Мнемокод типа события
    COUT                    out clob                               -- XML со свойствами раздела
  )
  is
    NCOMPANY                PKG_STD.TREF := GET_SESSION_COMPANY(); -- Рег. номер организации
  begin
    /* Формируем XML данных */
    PKG_XFAST.PROLOGUE(ITYPE => PKG_XFAST.CONTENT_);
    PKG_XFAST.DOWN_NODE(SNAME => 'DATA');
    /* Цикл по свойствам документа */
    for REC in (select CEP.PROPERTY,
                       CEP.PROPERTY_LINK,
                       DPL.NAME,
                       DPL.READONLY,
                       DPL.CHECK_VALUE,
                       DPL.CHECK_UNIQUE,
                       DPL.REQUIRE,
                       DPL.DUPLICATE_VALUE,
                       DPL.ACCESS_MODE,
                       DPL.SHOW_IN_GRID,
                       DPL.DEFAULT_STR,
                       DPL.DEFAULT_NUM,
                       DPL.DEFAULT_DATE,
                       DP.ENTRY_TYPE,
                       DP.FORMAT,
                       DP.DATA_SUBTYPE,
                       DP.NUM_WIDTH,
                       DP.NUM_PRECISION,
                       DP.STR_WIDTH,
                       DP.UNITCODE,
                       DP.PARAM_RN,
                       UP.IN_CODE,
                       UP.OUT_CODE,
                       DP.SHOW_METHOD_RN,
                       UM.METHOD_CODE,
                       DP.EXTRA_DICT_RN,
                       DP.INIT_RN
                  from CLEVTPROPS       CEP,
                       CLNEVNTYPES      CET,
                       DOCS_PROPS       DP,
                       DOCS_PROPS_LINKS DPL,
                       UNITPARAMS       UP,
                       UNIT_SHOWMETHODS UM
                 where CEP.PRN = CET.RN
                   and CET.EVNTYPE_CODE = SEVNTYPE_CODE
                   and CEP.COMPANY = NCOMPANY
                   and CEP.PROPERTY = DP.RN(+)
                   and CEP.PROPERTY_LINK = DPL.RN(+)
                   and (DP.PARAM_RN = UP.RN(+) and DP.UNITCODE = UP.UNITCODE(+))
                   and (DP.SHOW_METHOD_RN = UM.RN(+) and DP.UNITCODE = UM.UNITCODE(+))
                 order by DPL.POSITION)
    loop
      PKG_XFAST.DOWN_NODE(SNAME => 'XPROPS');
      /* Рег. номер свойства */
      PKG_XFAST.DOWN_NODE(SNAME => 'NRN');
      PKG_XFAST.VALUE(NVALUE => REC.PROPERTY);
      PKG_XFAST.UP();
      /* Наименование свойства */
      PKG_XFAST.DOWN_NODE(SNAME => 'SNAME');
      PKG_XFAST.VALUE(SVALUE => REC.NAME);
      PKG_XFAST.UP();
      /* Признак "только для чтения" */
      PKG_XFAST.DOWN_NODE(SNAME => 'BREADONLY');
      PKG_XFAST.VALUE(BVALUE => INT2BOOL(REC.READONLY));
      PKG_XFAST.UP();
      /* Признак "проверка/синхронизация вводимого значения" */
      PKG_XFAST.DOWN_NODE(SNAME => 'CHECK_VALUE');
      PKG_XFAST.VALUE(BVALUE => INT2BOOL(REC.CHECK_VALUE));
      PKG_XFAST.UP();
      /* Признак "проверка вводимого значения на уникальность" */
      PKG_XFAST.DOWN_NODE(SNAME => 'CHECK_UNIQUE');
      PKG_XFAST.VALUE(BVALUE => INT2BOOL(REC.CHECK_UNIQUE));
      PKG_XFAST.UP();
      /* Признак "обязательность к заполнению" */
      PKG_XFAST.DOWN_NODE(SNAME => 'BREQUIRE');
      PKG_XFAST.VALUE(BVALUE => INT2BOOL(REC.REQUIRE));
      PKG_XFAST.UP();
      /* Признак размножения */
      PKG_XFAST.DOWN_NODE(SNAME => 'DUPLICATE_VALUE');
      PKG_XFAST.VALUE(BVALUE => INT2BOOL(REC.DUPLICATE_VALUE));
      PKG_XFAST.UP();
      /* Уровень доступа к значениям свойства */
      PKG_XFAST.DOWN_NODE(SNAME => 'NACCESS_MODE');
      PKG_XFAST.VALUE(NVALUE => REC.ACCESS_MODE);
      PKG_XFAST.UP();
      /* Признак "показывать значение свойства в гриде раздела" */
      PKG_XFAST.DOWN_NODE(SNAME => 'BSHOW_IN_GRID');
      PKG_XFAST.VALUE(BVALUE => INT2BOOL(REC.SHOW_IN_GRID));
      PKG_XFAST.UP();
      /* Строка "по умолчанию" */
      PKG_XFAST.DOWN_NODE(SNAME => 'SDEFAULT_STR');
      PKG_XFAST.VALUE(SVALUE => REC.DEFAULT_STR);
      PKG_XFAST.UP();
      /* Число "по умолчанию" */
      PKG_XFAST.DOWN_NODE(SNAME => 'NDEFAULT_NUM');
      PKG_XFAST.VALUE(SVALUE => REC.DEFAULT_NUM);
      PKG_XFAST.UP();
      /* Дата "по умолчанию" */
      PKG_XFAST.DOWN_NODE(SNAME => 'DDEFAULT_DATE');
      PKG_XFAST.VALUE(DVALUE => REC.DEFAULT_DATE);
      PKG_XFAST.UP();
      /* Способ формирования */
      PKG_XFAST.DOWN_NODE(SNAME => 'NENTRY_TYPE');
      PKG_XFAST.VALUE(NVALUE => REC.ENTRY_TYPE);
      PKG_XFAST.UP();
      /* Формат данных */
      PKG_XFAST.DOWN_NODE(SNAME => 'NFORMAT');
      PKG_XFAST.VALUE(NVALUE => REC.FORMAT);
      PKG_XFAST.UP();
      /* Подтип */
      PKG_XFAST.DOWN_NODE(SNAME => 'NDATA_SUBTYPE');
      PKG_XFAST.VALUE(NVALUE => REC.DATA_SUBTYPE);
      PKG_XFAST.UP();
      /* Длина числа */
      PKG_XFAST.DOWN_NODE(SNAME => 'NNUM_WIDTH');
      PKG_XFAST.VALUE(NVALUE => REC.NUM_WIDTH);
      PKG_XFAST.UP();
      /* Точность числа */
      PKG_XFAST.DOWN_NODE(SNAME => 'NNUM_PRECISION');
      PKG_XFAST.VALUE(NVALUE => REC.NUM_PRECISION);
      PKG_XFAST.UP();
      /* Длина строки */
      PKG_XFAST.DOWN_NODE(SNAME => 'NSTR_WIDTH');
      PKG_XFAST.VALUE(NVALUE => REC.STR_WIDTH);
      PKG_XFAST.UP();
      /* Код раздела */
      PKG_XFAST.DOWN_NODE(SNAME => 'SUNITCODE');
      PKG_XFAST.VALUE(SVALUE => REC.UNITCODE);
      PKG_XFAST.UP();
      /* Рег. номер параметра раздела */
      PKG_XFAST.DOWN_NODE(SNAME => 'NPARAM_RN');
      PKG_XFAST.VALUE(NVALUE => REC.PARAM_RN);
      PKG_XFAST.UP();
      /* Код параметра раздела (входящий) */
      PKG_XFAST.DOWN_NODE(SNAME => 'SPARAM_IN_CODE');
      PKG_XFAST.VALUE(SVALUE => REC.IN_CODE);
      PKG_XFAST.UP();
      /* Код параметра раздела (исходящий) */
      PKG_XFAST.DOWN_NODE(SNAME => 'SPARAM_OUT_CODE');
      PKG_XFAST.VALUE(SVALUE => REC.OUT_CODE);
      PKG_XFAST.UP();
      /* Рег. номер метода вызова */
      PKG_XFAST.DOWN_NODE(SNAME => 'NSHOW_METHOD_RN');
      PKG_XFAST.VALUE(NVALUE => REC.SHOW_METHOD_RN);
      PKG_XFAST.UP();
      /* Код метода вызова */
      PKG_XFAST.DOWN_NODE(SNAME => 'SMETHOD_CODE');
      PKG_XFAST.VALUE(SVALUE => REC.METHOD_CODE);
      PKG_XFAST.UP();
      /* Рег. номер дополнительного словаря */
      PKG_XFAST.DOWN_NODE(SNAME => 'NEXTRA_DICT_RN');
      PKG_XFAST.VALUE(NVALUE => REC.EXTRA_DICT_RN);
      PKG_XFAST.UP();
      /* Рег. номер свойства инициализации */
      PKG_XFAST.DOWN_NODE(SNAME => 'NINIT_RN');
      PKG_XFAST.VALUE(NVALUE => REC.INIT_RN);
      PKG_XFAST.UP();
      /* Отформатированный рег. номер (как в доп. свойствах задачи) */
      PKG_XFAST.DOWN_NODE(SNAME => 'SFORMATTED_ID');
      PKG_XFAST.VALUE(SVALUE => UTL_DP_FORMATTED_ID_GET(NTYPE => REC.FORMAT, NRN => REC.PROPERTY));
      PKG_XFAST.UP();
      PKG_XFAST.UP();
    end loop;
    PKG_XFAST.UP();
    /* Сериализуем в CLOB */
    COUT := PKG_XFAST.SERIALIZE_TO_CLOB();
    PKG_XFAST.EPILOGUE();
  end CLNEVENTS_PROPS_GET;
  
  /* Загрузка статусов типа события */
  procedure CLNEVNSTATS_LOAD
  (
    SCLNEVNTYPES            in varchar2,                           -- Мнемокод типа события
    COUT                    out clob                               -- Статусы типа события
  )
  is
    NCOMPANY                PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса
    NINDEX                  PKG_STD.TREF := 0;                     -- Индекс статуса
  begin
    /* Начинаем формирование XML */
    PKG_XFAST.PROLOGUE(ITYPE => PKG_XFAST.CONTENT_);
    /* Открываем статусы */
    PKG_XFAST.DOWN_NODE(SNAME => 'XCLNEVNSTATS');
    /* Считываем статусы типа события */
    for REC in (select S.RN,
                       S.EVNSTAT_CODE,
                       S.EVNSTAT_NAME,
                       (select EP.COMMENTARY 
                          from EVROUTES     ER,
                               EVRTPOINTS   EP
                         where ER.EVENT_TYPE = T.RN 
                           and EP.PRN = ER.RN
                           and EP.EVENT_STATUS = TS.RN
                           and EP.COMMENTARY is not null
                           and rownum = 1) COMMENTARY
                  from CLNEVNTYPES  T,
                       CLNEVNTYPSTS TS,
                       CLNEVNSTATS  S
                 where T.COMPANY = NCOMPANY
                   and T.EVNTYPE_CODE = SCLNEVNTYPES
                   and TS.PRN = T.RN
                   and TS.EVENT_STATUS = S.RN
                 order by TS.DEFAULT_STATUS desc,
                          S.EVNSTAT_CODE)
    loop
      /* Открываем статус */
      PKG_XFAST.DOWN_NODE(SNAME => 'XSTATUS');
      /* Индекс статуса */
      PKG_XFAST.DOWN_NODE(SNAME => 'ID');
      PKG_XFAST.VALUE(NVALUE => NINDEX);
      PKG_XFAST.UP();
      /* Рег. номер статуса */
      PKG_XFAST.DOWN_NODE(SNAME => 'NRN');
      PKG_XFAST.VALUE(NVALUE => REC.RN);
      PKG_XFAST.UP();
      /* Мнемокод статуса */
      PKG_XFAST.DOWN_NODE(SNAME => 'SEVNSTAT_CODE');
      PKG_XFAST.VALUE(SVALUE => REC.EVNSTAT_CODE);
      PKG_XFAST.UP();
      /* Наименование статуса */
      PKG_XFAST.DOWN_NODE(SNAME => 'SEVNSTAT_NAME');
      PKG_XFAST.VALUE(SVALUE => REC.EVNSTAT_NAME);
      PKG_XFAST.UP();
      /* Описание в точке маршрута */
      PKG_XFAST.DOWN_NODE(SNAME => 'SEVPOINT_DESCR');
      PKG_XFAST.VALUE(SVALUE => COALESCE(REC.COMMENTARY, REC.EVNSTAT_NAME));
      PKG_XFAST.UP();
      /* Закрываем статус */
      PKG_XFAST.UP();
      /* Увеличиваем индекс статуса */
      NINDEX := NINDEX + 1;
    end loop;
    /* Закрываем статусы */
    PKG_XFAST.UP();
    /* Сериализуем */
    COUT := PKG_XFAST.SERIALIZE_TO_CLOB();
    /* Завершаем формирование XML */
    PKG_XFAST.EPILOGUE();
  exception
    when others then
      /* Завершаем формирование XML */
      PKG_XFAST.EPILOGUE();
      /* Вернем ошибку */
      PKG_STATE.DIAGNOSTICS_STACKED();
      P_EXCEPTION(0, PKG_STATE.SQL_ERRM());
  end CLNEVNSTATS_LOAD;

end PKG_P8PANELS_CLNTTSKBRD;
/
