1395 lines
92 KiB
SQL
1395 lines
92 KiB
SQL
create or replace package UDO_PKG_EQUIPTCF as
|
||
|
||
/* Формирование дерева состава оборудования */
|
||
procedure EQCONFIG_HIER
|
||
(
|
||
NEQPARENT in number, -- Рег. номер родительского узла состава оборудования
|
||
COUT out clob -- Сериализованное XML-представление дерева
|
||
);
|
||
|
||
/* Условия отбора технических объектов */
|
||
procedure EQCONFIG_THOBJ_LIST_COND;
|
||
|
||
/* Формирование списка технических объектов для выбранного узла состава оборудования */
|
||
procedure EQCONFIG_THOBJ_LIST
|
||
(
|
||
NEQPARENT in number, -- Рег. номер родительского узла состава оборудования
|
||
NPAGE_NUMBER in number, -- Номер страницы (игнорируется при NPAGE_SIZE=0)
|
||
NPAGE_SIZE in number, -- Количество записей на странице (0 - все)
|
||
CFILTERS in clob, -- Фильтры
|
||
CORDERS in clob, -- Сортировки
|
||
NINCLUDE_DEF in number, -- Признак включения описания колонок таблицы в ответ
|
||
COUT out clob -- Сериализованная таблица данных
|
||
);
|
||
|
||
/* Получение даты следующего технического обслуживания технического объекта */
|
||
function EQCONFIG_THOBJ_GET_NXTEQTCHSRV
|
||
(
|
||
NEQCONFIG in number, -- Рег. номер технического объекта
|
||
NSTATE in number := null -- Состояние (null - любое)
|
||
) return date; -- Дата следующего технического обслуживания
|
||
|
||
/* Выбор графиков технического обслуживания и ремонта технического объекта */
|
||
procedure EQCONFIG_THOBJ_SELECT_EQTCHSRV
|
||
(
|
||
NEQTCHSRV in number := null, -- Рег. номер графика ТО и ремонтов (null - любой)
|
||
NEQCONFIG in number := null, -- Рег. номер технического объекта (null - любой)
|
||
NSTATE in number := null, -- Состояние (null - любое)
|
||
NIDENT out number -- Идентификатор списка
|
||
);
|
||
|
||
/* Получение даты следующего ремонта по ремонтной ведомости технического объекта */
|
||
function EQCONFIG_THOBJ_GET_NXTEQRPSHT
|
||
(
|
||
NEQCONFIG in number, -- Рег. номер технического объекта
|
||
NSTATE in number := null -- Состояние (null - любое)
|
||
) return date; -- Дата следующего ремонта по ведомости
|
||
|
||
/* Выбор ремонтных ведомостей технического объекта */
|
||
procedure EQCONFIG_THOBJ_SELECT_EQRPSHT
|
||
(
|
||
NEQRPSHEETS in number := null, -- Рег. номер ремонтной ведосочти (null - любой)
|
||
NEQCONFIG in number := null, -- Рег. номер технического объекта (null - любой)
|
||
NSTATE in number := null, -- Состояние (null - любое)
|
||
NIDENT out number -- Идентификатор списка
|
||
);
|
||
|
||
/* Формирование карточки технического объекта */
|
||
procedure EQCONFIG_THOBJ_CARD
|
||
(
|
||
NEQCONFIG in number, -- Рег. номер технического объекта
|
||
COUT out clob -- Сериализованная карточка
|
||
);
|
||
|
||
/* Подчистка буферов после исполнения запроса на формирование прогноза технического объекта */
|
||
procedure EQCONFIG_THOBJ_FORECAST_BCLR
|
||
(
|
||
NDATASET_IDENT in number, -- Идентификатор буфера данных
|
||
NDATASET_CONFIG_IDENT in number, -- Идентификатор буфера описания данных
|
||
NREQUEST_CONFIG_IDENT in number -- Идентификатор буфера описания запроса
|
||
);
|
||
|
||
/* Подготовка запроса на формирование прогноза технического объекта */
|
||
procedure EQCONFIG_THOBJ_FORECAST_PRLG
|
||
(
|
||
NEQUIPDSCMML in number, -- Рег. номер модели
|
||
NDATASET_IDENT in number, -- Идентификатор буфера данных
|
||
NDATASET_CONFIG_IDENT in number, -- Идентификатор буфера описания данных
|
||
NREQUEST_CONFIG_IDENT in number, -- Идентификатор буфера описания запроса
|
||
SURL out varchar2, -- Адрес для запроса
|
||
SAUTH_TOKEN out varchar2, -- Токен аутентификации для запроса
|
||
SDATASET_ID out varchar2, -- Идентификатор выборки данных запроса
|
||
CDATASET_CONFIG out clob, -- Описание данных о наработках
|
||
SDATASET_URL out varchar2, -- Адрес для получения данных о наработках
|
||
SCLASS_MACHINE out varchar2, -- Код класса оборудования для запроса
|
||
STASK out varchar2 -- Задача для запроса (см. константы UDO_PKG_EQUIPDS_BASE.SCMML_TASK_*)
|
||
);
|
||
|
||
/* Финализация исполнения запроса на формирование прогноза технического объекта */
|
||
procedure EQCONFIG_THOBJ_FORECAST_EPLG
|
||
(
|
||
NDATASET_IDENT in number, -- Идентификатор буфера данных
|
||
NDATASET_CONFIG_IDENT in number, -- Идентификатор буфера описания данных
|
||
NREQUEST_CONFIG_IDENT in number, -- Идентификатор буфера описания запроса
|
||
NEQCONFIG in number := null, -- Рег. номер технического объекта
|
||
NEQUIPDSCMML in number := null, -- Рег. номер модели
|
||
CFORECAST in clob := null -- Данные прогноза
|
||
);
|
||
|
||
/* Формирование цвета прогноза для технического объекта */
|
||
function EQCONFIG_THOBJ_FORECAST_CLR
|
||
(
|
||
NMODE in number := 0, -- Режим работы (0 - для подсказки в колонке таблицы, 1 - для колонки таблицы, 2 - для карточки детализации
|
||
NVALUE in number :=0 -- Значение для подсветки
|
||
) return varchar2; -- Запрошенное значение в зависимости от режима
|
||
|
||
/* Формирование детальной карточки прогноза для технического объекта */
|
||
procedure EQCONFIG_THOBJ_FORECAST_CRD
|
||
(
|
||
NEQCONFIG in number, -- Рег. номер позиции состава оборудования
|
||
DFORECAST_DATE in date, -- Дата получения прогноза
|
||
NFORECAST in number, -- Прогнозное значение, полученное от фреймворка
|
||
SDICMUNTS in varchar2, -- Единица измерения выборки
|
||
STASK in varchar2, -- Задача (см. константы UDO_PKG_EQUIPDS_BASE.CMML_TASK_*)
|
||
COUT out clob -- Данные детальной карточки прогноза
|
||
);
|
||
|
||
/* Извлечение сведений из детальной карточки прогноза для технического объекта */
|
||
procedure EQCONFIG_THOBJ_FORECAST_CRDP
|
||
(
|
||
CFORECAST in clob, -- Данные детальной карточки прогноза
|
||
SFORECAST_DESC out varchar2, -- Описание прогноза
|
||
SFORECAST_DESC_COLOR out varchar2 -- Цвет заливки прогноза
|
||
);
|
||
|
||
/* Вероятность выхода единицы оборудования из строя с учётом графика ТО и ремонтов и RUL-прогноза */
|
||
function EQCONFIG_THOBJ_TCHSRV_BRKDPROB
|
||
(
|
||
NEQCONFIG in number -- Рег. номер технического объекта
|
||
) return number; -- Вероятность выхода из строя
|
||
|
||
/* Модификация графика ТО и ремонтов для технического объекта */
|
||
procedure EQCONFIG_THOBJ_CHNG_EQTCHSRV
|
||
(
|
||
NEQCONFIG in number, -- Рег. номер технического объекта
|
||
NEQTCHSRV in number, -- Рег. номер графика ТО и ремонтов
|
||
DPLANDATE_FROM in date -- Уточнённая плановая дата начала ремонта
|
||
);
|
||
|
||
/* Формирование ремонтной ведомости для технического объекта */
|
||
procedure EQCONFIG_THOBJ_MAKE_EQRPSHEET
|
||
(
|
||
NEQCONFIG in number, -- Рег. номер технического объекта
|
||
SACATALOG in varchar2, -- Каталог размещения ведомости
|
||
SEQTECSRVKIND in varchar2, -- Вид ремонта
|
||
DPLANDATE_FROM in date, -- Плановая дата начала ремонта
|
||
NIDENT out number -- Идентификатор списка сформированных ведомостей
|
||
);
|
||
|
||
end UDO_PKG_EQUIPTCF;
|
||
/
|
||
create or replace package body UDO_PKG_EQUIPTCF as
|
||
|
||
/*
|
||
TODO: owner="root" created="02.08.2024"
|
||
text="Проверка прав доступа при формировании таблицы и карточки ТО"
|
||
*/
|
||
|
||
/* Константы - адреса API фреймворка прогнозирования */
|
||
SFW_API_ROOT constant PKG_STD.TSTRING := '/API'; -- Корень API
|
||
SFW_API_FORECAST constant PKG_STD.TSTRING := '/forecast/metadata'; -- Адрес функции прогнозирования (относительно корня)
|
||
|
||
/* Формирование ветки дерева состава оборудования */
|
||
function EQCONFIG_HIER_NODE
|
||
(
|
||
NCUR in integer, -- Курсор документа для результата
|
||
NCOMPANY in number, -- Рег. номер организации
|
||
NEQPARENT in number -- Рег. номер родительского узла состава оборудования
|
||
) return PKG_XMAKE.TNODE -- XML-описание веток дерева
|
||
is
|
||
XLEAF PKG_XMAKE.TNODE; -- Текущий лист
|
||
XCHILD PKG_XMAKE.TNODE; -- Дочерние листы текущего
|
||
XRES PKG_XMAKE.TNODE; -- Буфер для результата
|
||
begin
|
||
/* Обходим состав оборудования с заданного корня */
|
||
for C in (select M.RN NRN,
|
||
M.EQPARENT NHRN,
|
||
DECODE(M.FICT_REC, 0, M.NAME, DECODE(OL.RN, null, M.NAME, OL.NAME)) SNAME,
|
||
case
|
||
when exists
|
||
(select null
|
||
from EQCONFIG C
|
||
where C.EQPARENT = M.RN
|
||
and exists (select null from V_USERPRIV_HIER_SINGL UP where UP.HIERARCHY = C.RN)) then
|
||
1
|
||
else
|
||
0
|
||
end NHASCHILDREN,
|
||
M.OBJ_KIND NOBJ_KIND
|
||
from EQCONFIG M,
|
||
EQOBJLEVEL OL
|
||
where M.PR_OBJ_LEVEL = OL.RN(+)
|
||
and ((M.FICT_REC = 0) or ((M.FICT_REC = 1) and (CMP_VC2(M.NAME, F_EQCONFIG_EXTRANAME(0)) = 1)))
|
||
and exists (select null from V_USERPRIV_HIER_SINGL UP where UP.HIERARCHY = M.RN)
|
||
and COALESCE(M.EQPARENT, 0) = NEQPARENT
|
||
and M.COMPANY = NCOMPANY
|
||
order by 3)
|
||
loop
|
||
/* Если есть дочерние ветки */
|
||
if (C.NHASCHILDREN = 1) then
|
||
/* Добавим фиктивную дочернюю запись для индикации наличия дочерних на клиенте */
|
||
XCHILD := PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
|
||
SNAME => 'children',
|
||
RATTRIBUTES => PKG_XMAKE.ATTRIBUTES(ICURSOR => NCUR,
|
||
RATTRIBUTE00 => PKG_XMAKE.ATTRIBUTE(ICURSOR => NCUR,
|
||
SNAME => 'id',
|
||
SVALUE => C.NRN ||
|
||
'_loader'),
|
||
RATTRIBUTE01 => PKG_XMAKE.ATTRIBUTE(ICURSOR => NCUR,
|
||
SNAME => 'label',
|
||
SVALUE => 'Минуточку...')));
|
||
/* Соберём лист */
|
||
XLEAF := PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
|
||
SNAME => 'children',
|
||
RATTRIBUTES => PKG_XMAKE.ATTRIBUTES(ICURSOR => NCUR,
|
||
RATTRIBUTE00 => PKG_XMAKE.ATTRIBUTE(ICURSOR => NCUR,
|
||
SNAME => 'id',
|
||
SVALUE => C.NRN),
|
||
RATTRIBUTE01 => PKG_XMAKE.ATTRIBUTE(ICURSOR => NCUR,
|
||
SNAME => 'label',
|
||
SVALUE => C.SNAME)),
|
||
RNODE00 => XCHILD);
|
||
/* Соберём листы в ветку */
|
||
XRES := PKG_XMAKE.CONCAT(ICURSOR => NCUR, RNODE00 => XRES, RNODE01 => XLEAF);
|
||
end if;
|
||
end loop;
|
||
/* Вернём собранное */
|
||
return XRES;
|
||
end EQCONFIG_HIER_NODE;
|
||
|
||
/* Формирование дерева состава оборудования */
|
||
procedure EQCONFIG_HIER
|
||
(
|
||
NEQPARENT in number, -- Рег. номер родительского узла состава оборудования
|
||
COUT out clob -- Сериализованное XML-представление дерева
|
||
)
|
||
is
|
||
NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Рег. номер организации
|
||
NCUR integer; -- Курсор документа для результата
|
||
XDOC PKG_XMAKE.TNODE; -- Документ для результата
|
||
begin
|
||
/* Открываем документ */
|
||
NCUR := PKG_XMAKE.OPEN_CURSOR();
|
||
/* Формируем XML-представление ветки для запрошенного родителя */
|
||
XDOC := PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
|
||
SNAME => 'XDATA',
|
||
RNODE00 => EQCONFIG_HIER_NODE(NCUR => NCUR, NCOMPANY => NCOMPANY, NEQPARENT => NEQPARENT));
|
||
/* Конвертируем в CLOB */
|
||
COUT := PKG_XMAKE.SERIALIZE_TO_CLOB(ICURSOR => NCUR,
|
||
ITYPE => PKG_XMAKE.CONTENT_,
|
||
RNODE => XDOC,
|
||
RHEADER => PKG_XHEADER.WRAP_ALL(SVERSION => PKG_XHEADER.VERSION_1_0_,
|
||
SENCODING => PKG_XHEADER.ENCODING_UTF_,
|
||
SSTANDALONE => PKG_XHEADER.STANDALONE_YES_));
|
||
/* Закрываем документ */
|
||
PKG_XMAKE.CLOSE_CURSOR(ICURSOR => NCUR);
|
||
end EQCONFIG_HIER;
|
||
|
||
/* Условия отбора технических объектов */
|
||
procedure EQCONFIG_THOBJ_LIST_COND
|
||
is
|
||
begin
|
||
/* Установка главной таблицы */
|
||
PKG_COND_BROKER.SET_TABLE(STABLE_NAME => 'EQCONFIG');
|
||
/* Обозначение */
|
||
PKG_COND_BROKER.ADD_CONDITION_CODE(SCOLUMN_NAME => 'CODE', SCONDITION_NAME => 'SCODEFrom');
|
||
/* Наименование */
|
||
PKG_COND_BROKER.ADD_CONDITION_CODE(SCOLUMN_NAME => 'NAME', SCONDITION_NAME => 'SNAMEFrom');
|
||
/* Дата ввода в эксплуатацию */
|
||
PKG_COND_BROKER.ADD_CONDITION_BETWEEN(SCOLUMN_NAME => 'OPER_DATE',
|
||
SCONDITION_NAME_FROM => 'DOPER_DATEFrom',
|
||
SCONDITION_NAME_TO => 'DOPER_DATETo');
|
||
/* Состояние */
|
||
PKG_COND_BROKER.ADD_CONDITION_CODE(SCOLUMN_NAME => 'CODE',
|
||
SCONDITION_NAME => 'SUSE_KINDFrom',
|
||
SJOINS => 'HLSTATETYPES <- RN;HLSTATETYPES');
|
||
/* Класс */
|
||
PKG_COND_BROKER.ADD_CONDITION_CODE(SCOLUMN_NAME => 'NAME',
|
||
SCONDITION_NAME => 'SOBJ_KINDFrom',
|
||
SJOINS => 'OBJ_KIND <- RN;EQOBJKIND');
|
||
/* Действия с моделями прогнозирования */
|
||
if (PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'NCMML_STATUSFrom') = 1) then
|
||
PKG_COND_BROKER.ADD_CLAUSE(SCLAUSE => PKG_SQL_BUILD.PKG_NAME(SNAME => 'UDO_PKG_EQUIPDS.CMML_STATUS_BY_EQCONFIG') ||
|
||
'(RN) = :NCMML_STATUS');
|
||
PKG_COND_BROKER.BIND_VARIABLE(SVARIABLE_NAME => 'NCMML_STATUS',
|
||
SVALUE => PKG_COND_BROKER.GET_CONDITION_NUM(SCONDITION_NAME => 'NCMML_STATUSFrom'));
|
||
end if;
|
||
/* Вероятность выхода из строя */
|
||
if ((PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'NBREAKDOWN_PROBFrom') = 1) and
|
||
(PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'NBREAKDOWN_PROBTo') = 0)) then
|
||
PKG_COND_BROKER.ADD_CLAUSE(SCLAUSE => PKG_SQL_BUILD.PKG_NAME(SNAME => 'UDO_PKG_EQUIPTCF.EQCONFIG_THOBJ_TCHSRV_BRKDPROB') ||
|
||
'(RN) >= :NBREAKDOWN_PROBFrom');
|
||
PKG_COND_BROKER.BIND_VARIABLE(SVARIABLE_NAME => 'NBREAKDOWN_PROBFrom',
|
||
NVALUE => PKG_COND_BROKER.GET_CONDITION_NUM(SCONDITION_NAME => 'NBREAKDOWN_PROBFrom'));
|
||
end if;
|
||
if ((PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'NBREAKDOWN_PROBTo') = 1) and
|
||
(PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'NBREAKDOWN_PROBFrom') = 0)) then
|
||
PKG_COND_BROKER.ADD_CLAUSE(SCLAUSE => PKG_SQL_BUILD.PKG_NAME(SNAME => 'UDO_PKG_EQUIPTCF.EQCONFIG_THOBJ_TCHSRV_BRKDPROB') ||
|
||
'(RN) <= :NBREAKDOWN_PROBTo');
|
||
PKG_COND_BROKER.BIND_VARIABLE(SVARIABLE_NAME => 'NBREAKDOWN_PROBTo',
|
||
NVALUE => PKG_COND_BROKER.GET_CONDITION_NUM(SCONDITION_NAME => 'NBREAKDOWN_PROBTo'));
|
||
end if;
|
||
if ((PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'NBREAKDOWN_PROBFrom') = 1) and
|
||
(PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'NBREAKDOWN_PROBTo') = 1)) then
|
||
PKG_COND_BROKER.ADD_CLAUSE(SCLAUSE => PKG_SQL_BUILD.PKG_NAME(SNAME => 'UDO_PKG_EQUIPTCF.EQCONFIG_THOBJ_TCHSRV_BRKDPROB') ||
|
||
'(RN) between :NBREAKDOWN_PROBFrom and :NBREAKDOWN_PROBTo');
|
||
PKG_COND_BROKER.BIND_VARIABLE(SVARIABLE_NAME => 'NBREAKDOWN_PROBFrom',
|
||
NVALUE => PKG_COND_BROKER.GET_CONDITION_NUM(SCONDITION_NAME => 'NBREAKDOWN_PROBFrom'));
|
||
PKG_COND_BROKER.BIND_VARIABLE(SVARIABLE_NAME => 'NBREAKDOWN_PROBTo',
|
||
NVALUE => PKG_COND_BROKER.GET_CONDITION_NUM(SCONDITION_NAME => 'NBREAKDOWN_PROBTo'));
|
||
end if;
|
||
end EQCONFIG_THOBJ_LIST_COND;
|
||
|
||
/* Формирование списка технических объектов для выбранного узла состава оборудования */
|
||
procedure EQCONFIG_THOBJ_LIST
|
||
(
|
||
NEQPARENT in number, -- Рег. номер родительского узла состава оборудования
|
||
NPAGE_NUMBER in number, -- Номер страницы (игнорируется при NPAGE_SIZE=0)
|
||
NPAGE_SIZE in number, -- Количество записей на странице (0 - все)
|
||
CFILTERS in clob, -- Фильтры
|
||
CORDERS in clob, -- Сортировки
|
||
NINCLUDE_DEF in number, -- Признак включения описания колонок таблицы в ответ
|
||
COUT out clob -- Сериализованная таблица данных
|
||
)
|
||
is
|
||
NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса
|
||
NIDENT PKG_STD.TREF := GEN_IDENT(); -- Идентификатор отбора
|
||
RF PKG_P8PANELS_VISUAL.TDG_FILTERS; -- Фильтры
|
||
RO PKG_P8PANELS_VISUAL.TDG_ORDERS; -- Сортировки
|
||
RDG PKG_P8PANELS_VISUAL.TDG; -- Описание таблицы
|
||
RDG_ROW PKG_P8PANELS_VISUAL.TDG_ROW; -- Строка таблицы
|
||
RCOL_VALS PKG_P8PANELS_VISUAL.TDG_COL_VALS; -- Предопределённые значения столбцов
|
||
NROW_FROM PKG_STD.TREF; -- Номер строки с
|
||
NROW_TO PKG_STD.TREF; -- Номер строки по
|
||
CSQL clob; -- Буфер для запроса
|
||
ICURSOR integer; -- Курсор для исполнения запроса
|
||
NBREAKDOWN_PROB PKG_STD.TNUMBER; -- Вероятность выхода единицы оборудования из строя
|
||
begin
|
||
/* Читаем фильтры */
|
||
RF := PKG_P8PANELS_VISUAL.TDG_FILTERS_FROM_XML(CFILTERS => CFILTERS);
|
||
/* Читаем сортировки */
|
||
RO := PKG_P8PANELS_VISUAL.TDG_ORDERS_FROM_XML(CORDERS => CORDERS);
|
||
/* Преобразуем номер и размер страницы в номер строк с и по */
|
||
PKG_P8PANELS_VISUAL.UTL_ROWS_LIMITS_CALC(NPAGE_NUMBER => NPAGE_NUMBER,
|
||
NPAGE_SIZE => NPAGE_SIZE,
|
||
NROW_FROM => NROW_FROM,
|
||
NROW_TO => NROW_TO);
|
||
/* Инициализируем таблицу данных */
|
||
RDG := PKG_P8PANELS_VISUAL.TDG_MAKE();
|
||
/* Добавляем в таблицу описание колонок */
|
||
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 => 'SCODE',
|
||
SCAPTION => 'Обозначение',
|
||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
|
||
BORDER => true,
|
||
BFILTER => true);
|
||
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
|
||
SNAME => 'SNAME',
|
||
SCAPTION => 'Наименование',
|
||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
|
||
BORDER => true,
|
||
BFILTER => true);
|
||
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
|
||
SNAME => 'DOPER_DATE',
|
||
SCAPTION => 'Дата ввода в эксплуатацию',
|
||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_DATE,
|
||
BORDER => true,
|
||
BFILTER => true);
|
||
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
|
||
SNAME => 'SUSE_KIND',
|
||
SCAPTION => 'Состояние',
|
||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
|
||
BORDER => true,
|
||
BFILTER => true);
|
||
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
|
||
SNAME => 'NOBJ_KIND',
|
||
SCAPTION => 'Рег. номер класса технического объекта',
|
||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
|
||
BVISIBLE => false);
|
||
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
|
||
SNAME => 'SOBJ_KIND',
|
||
SCAPTION => 'Класс',
|
||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
|
||
BORDER => true,
|
||
BFILTER => true);
|
||
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
|
||
SNAME => 'SOBJ_KIND_FULL_CODE',
|
||
SCAPTION => 'Класс (полный иерархический код)',
|
||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
|
||
BVISIBLE => false);
|
||
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
|
||
SNAME => 'SUMEAS_RES',
|
||
SCAPTION => 'Единица измерения ресурса',
|
||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
|
||
BVISIBLE => false);
|
||
PKG_P8PANELS_VISUAL.TDG_COL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 0, BCLEAR => true);
|
||
PKG_P8PANELS_VISUAL.TDG_COL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 1);
|
||
PKG_P8PANELS_VISUAL.TDG_COL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 2);
|
||
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
|
||
SNAME => 'NCMML_STATUS',
|
||
SCAPTION => 'Модель',
|
||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
|
||
BORDER => true,
|
||
BFILTER => true,
|
||
RCOL_VALS => RCOL_VALS);
|
||
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
|
||
SNAME => 'NBREAKDOWN_PROB',
|
||
SCAPTION => 'Вероятность выхода из строя',
|
||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
|
||
BORDER => true,
|
||
BFILTER => true,
|
||
SHINT => EQCONFIG_THOBJ_FORECAST_CLR(NMODE => 0));
|
||
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
|
||
SNAME => 'SBREAKDOWN_PROB_COLOR',
|
||
SCAPTION => 'Цвет вероятности выхода из строя',
|
||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
|
||
BVISIBLE => false);
|
||
/* Обходим данные */
|
||
begin
|
||
/* Добавляем подсказку совместимости */
|
||
CSQL := PKG_SQL_BUILD.COMPATIBLE(SSQL => CSQL);
|
||
/* Формируем запрос */
|
||
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => 'select *');
|
||
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from (select D.*,');
|
||
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.SQLROWNUM() || ' NROW');
|
||
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from (select C.RN NRN,');
|
||
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' C.CODE SCODE,');
|
||
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' C."NAME" SNAME,');
|
||
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' C.OPER_DATE DOPER_DATE,');
|
||
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' ST.CODE SUSE_KIND,');
|
||
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' C.OBJ_KIND NOBJ_KIND,');
|
||
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' OK.NAME SOBJ_KIND,');
|
||
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' FORMAT_HIER_NAME(OK.COMPANY, null, OK.FULLCODE) SOBJ_KIND_FULL_CODE,');
|
||
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' DM.MEAS_MNEMO SUMEAS_RES,');
|
||
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.PKG_NAME(SNAME => 'UDO_PKG_EQUIPDS.CMML_STATUS_BY_EQCONFIG') || '(C.RN) NCMML_STATUS,');
|
||
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.PKG_NAME(SNAME => 'UDO_PKG_EQUIPTCF.EQCONFIG_THOBJ_TCHSRV_BRKDPROB') || '(C.RN) NBREAKDOWN_PROB');
|
||
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from EQCONFIG C');
|
||
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' left outer join HLSTATETYPES ST on C.HLSTATETYPES = ST.RN');
|
||
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' left outer join DICMUNTS DM on C.UMEAS_RES = DM.RN,');
|
||
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' EQOBJKIND OK');
|
||
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' where C.EQPARENT = :NEQPARENT');
|
||
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and C.OBJ_KIND = OK.RN');
|
||
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and C.RN in (select ID from COND_BROKER_IDSMART where IDENT = :NIDENT) %ORDER_BY%) D) F');
|
||
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' where F.NROW between :NROW_FROM and :NROW_TO');
|
||
/* Учтём сортировки */
|
||
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 => 'EquipConfiguration',
|
||
SPROCEDURE => PKG_SQL_BUILD.PKG_NAME(SNAME => 'UDO_PKG_EQUIPTCF.EQCONFIG_THOBJ_LIST_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 => 'NEQPARENT', NVALUE => NEQPARENT);
|
||
PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NIDENT', NVALUE => NIDENT);
|
||
PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NROW_FROM', NVALUE => NROW_FROM);
|
||
PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NROW_TO', NVALUE => NROW_TO);
|
||
/* Описываем структуру записи курсора */
|
||
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_DATE(ICURSOR => ICURSOR, IPOSITION => 4);
|
||
PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 5);
|
||
PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 6);
|
||
PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 7);
|
||
PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 8);
|
||
PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 9);
|
||
PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 10);
|
||
PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 11);
|
||
PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 12);
|
||
/* Делаем выборку */
|
||
if (PKG_SQL_DML.EXECUTE(ICURSOR => ICURSOR) = 0) then
|
||
null;
|
||
end if;
|
||
/* Обходим выбранные записи */
|
||
while (PKG_SQL_DML.FETCH_ROWS(ICURSOR => ICURSOR) > 0)
|
||
loop
|
||
/* Добавляем колонки с данными */
|
||
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
|
||
SNAME => 'NRN',
|
||
ICURSOR => ICURSOR,
|
||
NPOSITION => 1,
|
||
BCLEAR => true);
|
||
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SCODE', ICURSOR => ICURSOR, NPOSITION => 2);
|
||
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SNAME', ICURSOR => ICURSOR, NPOSITION => 3);
|
||
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLD(RROW => RDG_ROW,
|
||
SNAME => 'DOPER_DATE',
|
||
ICURSOR => ICURSOR,
|
||
NPOSITION => 4);
|
||
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
|
||
SNAME => 'SUSE_KIND',
|
||
ICURSOR => ICURSOR,
|
||
NPOSITION => 5);
|
||
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
|
||
SNAME => 'NOBJ_KIND',
|
||
ICURSOR => ICURSOR,
|
||
NPOSITION => 6);
|
||
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
|
||
SNAME => 'SOBJ_KIND',
|
||
ICURSOR => ICURSOR,
|
||
NPOSITION => 7);
|
||
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
|
||
SNAME => 'SOBJ_KIND_FULL_CODE',
|
||
ICURSOR => ICURSOR,
|
||
NPOSITION => 8);
|
||
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
|
||
SNAME => 'SUMEAS_RES',
|
||
ICURSOR => ICURSOR,
|
||
NPOSITION => 9);
|
||
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
|
||
SNAME => 'NCMML_STATUS',
|
||
ICURSOR => ICURSOR,
|
||
NPOSITION => 10);
|
||
PKG_SQL_DML.COLUMN_VALUE_NUM(ICURSOR => ICURSOR, IPOSITION => 11, NVALUE => NBREAKDOWN_PROB);
|
||
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NBREAKDOWN_PROB', NVALUE => NBREAKDOWN_PROB);
|
||
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW,
|
||
SNAME => 'SBREAKDOWN_PROB_COLOR',
|
||
SVALUE => EQCONFIG_THOBJ_FORECAST_CLR(NMODE => 1, NVALUE => NBREAKDOWN_PROB));
|
||
/* Добавляем строку в таблицу */
|
||
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 => NINCLUDE_DEF);
|
||
end EQCONFIG_THOBJ_LIST;
|
||
|
||
/* Получение даты следующего технического обслуживания технического объекта */
|
||
function EQCONFIG_THOBJ_GET_NXTEQTCHSRV
|
||
(
|
||
NEQCONFIG in number, -- Рег. номер технического объекта
|
||
NSTATE in number := null -- Состояние (null - любое)
|
||
) return date -- Дата следующего технического обслуживания
|
||
is
|
||
DRES PKG_STD.TLDATE; -- Буфер для результата
|
||
begin
|
||
/* Найдем график ТО и ремонтов, в заданном состоянии, с минимальной датой по данному тех. объекту */
|
||
select min(T.DATEPRD_BEG)
|
||
into DRES
|
||
from EQTCHSRV T
|
||
where T.EQCONFIG_TECH = NEQCONFIG
|
||
and ((NSTATE is null) or ((NSTATE is not null) and (T.STATE = NSTATE)))
|
||
and T.DATEPRD_BEG >= sysdate;
|
||
/* Вернём результат */
|
||
return DRES;
|
||
exception
|
||
when others then
|
||
return null;
|
||
end EQCONFIG_THOBJ_GET_NXTEQTCHSRV;
|
||
|
||
/* Выбор графиков технического обслуживания и ремонта технического объекта */
|
||
procedure EQCONFIG_THOBJ_SELECT_EQTCHSRV
|
||
(
|
||
NEQTCHSRV in number := null, -- Рег. номер графика ТО и ремонтов (null - любой)
|
||
NEQCONFIG in number := null, -- Рег. номер технического объекта (null - любой)
|
||
NSTATE in number := null, -- Состояние (null - любое)
|
||
NIDENT out number -- Идентификатор списка
|
||
)
|
||
is
|
||
NTMP PKG_STD.TREF; -- Рег. номер записи буфера отобранных
|
||
begin
|
||
/* Обходим графики по тех. объекту */
|
||
for C in (select T.RN
|
||
from EQTCHSRV T
|
||
where ((NEQTCHSRV is null) or ((NEQTCHSRV is not null) and (T.RN = NEQTCHSRV)))
|
||
and ((NEQCONFIG is null) or ((NEQCONFIG is not null) and (T.EQCONFIG_TECH = NEQCONFIG)))
|
||
and ((NEQTCHSRV is not null) or ((NEQTCHSRV is null) and (T.DATEPRD_BEG >= sysdate)))
|
||
and ((NSTATE is null) or ((NSTATE is not null) and (T.STATE = NSTATE))))
|
||
loop
|
||
/* Формируем идентификатор списка если необходимо */
|
||
if (NIDENT is null) then
|
||
NIDENT := GEN_IDENT();
|
||
end if;
|
||
/* Добавляем отобранное в список */
|
||
P_SELECTLIST_INSERT(NIDENT => NIDENT, NDOCUMENT => C.RN, SUNITCODE => 'EquipTechServices', NRN => NTMP);
|
||
end loop;
|
||
end EQCONFIG_THOBJ_SELECT_EQTCHSRV;
|
||
|
||
/* Получение даты следующего ремонта по ремонтной ведомости технического объекта */
|
||
function EQCONFIG_THOBJ_GET_NXTEQRPSHT
|
||
(
|
||
NEQCONFIG in number, -- Рег. номер технического объекта
|
||
NSTATE in number := null -- Состояние (null - любое)
|
||
) return date -- Дата следующего ремонта по ведомости
|
||
is
|
||
DRES PKG_STD.TLDATE; -- Буфер для результата
|
||
begin
|
||
/* Найдем график ТО и ремонтов, в заданном состоянии, с минимальной датой по данному тех. объекту */
|
||
select min(T.DATEPLAN_BEG)
|
||
into DRES
|
||
from EQRPSHEETS T
|
||
where T.EQCONFIG = NEQCONFIG
|
||
and ((NSTATE is null) or ((NSTATE is not null) and (T.STATE = NSTATE)))
|
||
and T.DATEPLAN_BEG >= sysdate;
|
||
/* Вернём результат */
|
||
return DRES;
|
||
exception
|
||
when others then
|
||
return null;
|
||
end EQCONFIG_THOBJ_GET_NXTEQRPSHT;
|
||
|
||
/* Выбор ремонтных ведомостей технического объекта */
|
||
procedure EQCONFIG_THOBJ_SELECT_EQRPSHT
|
||
(
|
||
NEQRPSHEETS in number := null, -- Рег. номер ремонтной ведосочти (null - любой)
|
||
NEQCONFIG in number := null, -- Рег. номер технического объекта (null - любой)
|
||
NSTATE in number := null, -- Состояние (null - любое)
|
||
NIDENT out number -- Идентификатор списка
|
||
)
|
||
is
|
||
NTMP PKG_STD.TREF; -- Рег. номер записи буфера отобранных
|
||
begin
|
||
/* Обходим графики по тех. объекту */
|
||
for C in (select T.RN
|
||
from EQRPSHEETS T
|
||
where ((NEQRPSHEETS is null) or ((NEQRPSHEETS is not null) and (T.RN = NEQRPSHEETS)))
|
||
and ((NEQCONFIG is null) or ((NEQCONFIG is not null) and (T.EQCONFIG = NEQCONFIG)))
|
||
and ((NEQRPSHEETS is not null) or ((NEQRPSHEETS is null) and (T.DATEPLAN_BEG >= sysdate)))
|
||
and ((NSTATE is null) or ((NSTATE is not null) and (T.STATE = NSTATE))))
|
||
loop
|
||
/* Формируем идентификатор списка если необходимо */
|
||
if (NIDENT is null) then
|
||
NIDENT := GEN_IDENT();
|
||
end if;
|
||
/* Добавляем отобранное в список */
|
||
P_SELECTLIST_INSERT(NIDENT => NIDENT, NDOCUMENT => C.RN, SUNITCODE => 'EquipRepairSheets', NRN => NTMP);
|
||
end loop;
|
||
end EQCONFIG_THOBJ_SELECT_EQRPSHT;
|
||
|
||
/* Получение даты следующего ремонта по ремонтной ведомости или графику ТО и ремонтов (что раньше) технического объекта */
|
||
function EQCONFIG_THOBJ_GEN_NXTRPR
|
||
(
|
||
NEQCONFIG in number -- Рег. номер технического объекта
|
||
) return date -- Дата ближайшего ремонта
|
||
is
|
||
DNXTEQTCHSRV PKG_STD.TLDATE; -- Дата ближайшего ТО или ремонта по графику
|
||
DNXTEQRPSHT PKG_STD.TLDATE; -- Дата ближайшего ТО или ремонта по ремонтным ведомостям
|
||
DRES PKG_STD.TLDATE; -- Буфер для результата
|
||
begin
|
||
/* Определим дату ближайшего ТО или ремонта */
|
||
DNXTEQTCHSRV := EQCONFIG_THOBJ_GET_NXTEQTCHSRV(NEQCONFIG => NEQCONFIG);
|
||
/* Определим дату ближайшей ремонтной ведомости */
|
||
DNXTEQRPSHT := EQCONFIG_THOBJ_GET_NXTEQRPSHT(NEQCONFIG => NEQCONFIG);
|
||
/* Берм меньшую */
|
||
if ((DNXTEQRPSHT is not null) and (DNXTEQTCHSRV is not null)) then
|
||
if (DNXTEQRPSHT < DNXTEQTCHSRV) then
|
||
DRES := DNXTEQRPSHT;
|
||
else
|
||
DRES := DNXTEQTCHSRV;
|
||
end if;
|
||
else
|
||
DRES := COALESCE(DNXTEQTCHSRV, DNXTEQRPSHT);
|
||
end if;
|
||
/* Вернём результат */
|
||
return DRES;
|
||
end EQCONFIG_THOBJ_GEN_NXTRPR;
|
||
|
||
/* Формирование карточки технического объекта */
|
||
procedure EQCONFIG_THOBJ_CARD
|
||
(
|
||
NEQCONFIG in number, -- Рег. номер технического объекта
|
||
COUT out clob -- Сериализованная карточка
|
||
)
|
||
is
|
||
NCUR integer; -- Курсор документа для результата
|
||
XDOC PKG_XMAKE.TNODE; -- Документ для результата
|
||
XCARD PKG_XMAKE.TNODE; -- XML-карточка
|
||
begin
|
||
/* Открываем документ */
|
||
NCUR := PKG_XMAKE.OPEN_CURSOR();
|
||
/* Обратимся к данным технического объекта */
|
||
for C in (select T.RN NRN,
|
||
T.CODE SCODE,
|
||
T.NAME SNAME,
|
||
T.OPER_DATE DOPER_DATE,
|
||
OK.NAME SEQOBJKIND
|
||
from EQCONFIG T,
|
||
EQOBJKIND OK
|
||
where T.RN = NEQCONFIG
|
||
and T.OBJ_KIND = OK.RN)
|
||
loop
|
||
/* Соберем карточку */
|
||
XCARD := PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
|
||
SNAME => 'techObj',
|
||
RATTRIBUTES => PKG_XMAKE.ATTRIBUTES(ICURSOR => NCUR,
|
||
RATTRIBUTE00 => PKG_XMAKE.ATTRIBUTE(ICURSOR => NCUR,
|
||
SNAME => 'NRN',
|
||
NVALUE => C.NRN),
|
||
RATTRIBUTE01 => PKG_XMAKE.ATTRIBUTE(ICURSOR => NCUR,
|
||
SNAME => 'SCODE',
|
||
SVALUE => C.SCODE),
|
||
RATTRIBUTE02 => PKG_XMAKE.ATTRIBUTE(ICURSOR => NCUR,
|
||
SNAME => 'SNAME',
|
||
SVALUE => C.SNAME),
|
||
RATTRIBUTE03 => PKG_XMAKE.ATTRIBUTE(ICURSOR => NCUR,
|
||
SNAME => 'DOPER_DATE',
|
||
DVALUE => C.DOPER_DATE),
|
||
RATTRIBUTE04 => PKG_XMAKE.ATTRIBUTE(ICURSOR => NCUR,
|
||
SNAME => 'DNEXT_EQTCHSRV',
|
||
SVALUE => TO_CHAR(EQCONFIG_THOBJ_GET_NXTEQTCHSRV(NEQCONFIG => C.NRN),
|
||
'dd.mm.yyyy hh24:mi:ss')),
|
||
RATTRIBUTE05 => PKG_XMAKE.ATTRIBUTE(ICURSOR => NCUR,
|
||
SNAME => 'DNEXT_EQRPSHEET',
|
||
SVALUE => TO_CHAR(EQCONFIG_THOBJ_GET_NXTEQRPSHT(NEQCONFIG => C.NRN),
|
||
'dd.mm.yyyy hh24:mi:ss')),
|
||
RATTRIBUTE06 => PKG_XMAKE.ATTRIBUTE(ICURSOR => NCUR,
|
||
SNAME => 'SEQOBJKIND',
|
||
SVALUE => C.SEQOBJKIND)));
|
||
end loop;
|
||
/* Формируем XML-представление документа ответа */
|
||
XDOC := PKG_XMAKE.ELEMENT(ICURSOR => NCUR, SNAME => 'XDATA', RNODE00 => XCARD);
|
||
/* Сериализуем документ */
|
||
COUT := PKG_XMAKE.SERIALIZE_TO_CLOB(ICURSOR => NCUR,
|
||
ITYPE => PKG_XMAKE.CONTENT_,
|
||
RNODE => XDOC,
|
||
RHEADER => PKG_XHEADER.WRAP_ALL(SVERSION => PKG_XHEADER.VERSION_1_0_,
|
||
SENCODING => PKG_XHEADER.ENCODING_UTF_,
|
||
SSTANDALONE => PKG_XHEADER.STANDALONE_YES_));
|
||
/* Закрываем документ */
|
||
PKG_XMAKE.CLOSE_CURSOR(ICURSOR => NCUR);
|
||
end EQCONFIG_THOBJ_CARD;
|
||
|
||
/* Подчистка буферов после исполнения запроса на формирование прогноза технического объекта */
|
||
procedure EQCONFIG_THOBJ_FORECAST_BCLR
|
||
(
|
||
NDATASET_IDENT in number, -- Идентификатор буфера данных
|
||
NDATASET_CONFIG_IDENT in number, -- Идентификатор буфера описания данных
|
||
NREQUEST_CONFIG_IDENT in number -- Идентификатор буфера описания запроса
|
||
)
|
||
is
|
||
begin
|
||
/* Очистим данные в файловом буфере */
|
||
P_FILE_BUFFER_CLEAR(NIDENT => NDATASET_IDENT);
|
||
P_FILE_BUFFER_CLEAR(NIDENT => NDATASET_CONFIG_IDENT);
|
||
P_FILE_BUFFER_CLEAR(NIDENT => NREQUEST_CONFIG_IDENT);
|
||
end EQCONFIG_THOBJ_FORECAST_BCLR;
|
||
|
||
/* Подчистка буферов после исполнения запроса на формирование прогноза технического объекта (в автономной транзакции) */
|
||
procedure EQCONFIG_THOBJ_FORECAST_BCLRAT
|
||
(
|
||
NDATASET_IDENT in number, -- Идентификатор буфера данных
|
||
NDATASET_CONFIG_IDENT in number, -- Идентификатор буфера описания данных
|
||
NREQUEST_CONFIG_IDENT in number -- Идентификатор буфера описания запроса
|
||
)
|
||
is
|
||
RPROC_PARAMS PKG_CONTPRMLOC.TCONTAINER; -- Параметры процедуры
|
||
begin
|
||
/* Очищаем контейнер с параметрами */
|
||
PKG_CONTPRMLOC.PURGE(RCONTAINER => RPROC_PARAMS);
|
||
/* Собираем параметры процедуры */
|
||
PKG_CONTPRMLOC.PUTN(RCONTAINER => RPROC_PARAMS,
|
||
SNAME => 'NDATASET_IDENT',
|
||
NVALUE => NDATASET_IDENT,
|
||
NIN_OUT => PKG_STD.PARAM_TYPE_IN());
|
||
PKG_CONTPRMLOC.PUTN(RCONTAINER => RPROC_PARAMS,
|
||
SNAME => 'NDATASET_CONFIG_IDENT',
|
||
NVALUE => NDATASET_CONFIG_IDENT,
|
||
NIN_OUT => PKG_STD.PARAM_TYPE_IN());
|
||
PKG_CONTPRMLOC.PUTN(RCONTAINER => RPROC_PARAMS,
|
||
SNAME => 'NREQUEST_CONFIG_IDENT',
|
||
NVALUE => NREQUEST_CONFIG_IDENT,
|
||
NIN_OUT => PKG_STD.PARAM_TYPE_IN());
|
||
/* Подчищаем (в автономной транзакции) */
|
||
PKG_SQL_CALL.EXECUTE_STORED_AT(SSTORED_NAME => 'UDO_PKG_EQUIPTCF.EQCONFIG_THOBJ_FORECAST_BCLR',
|
||
RPARAM_CONTAINER => RPROC_PARAMS,
|
||
BOVERLOAD_ENV => true);
|
||
/* Очищаем контейнер с параметрами */
|
||
PKG_CONTPRMLOC.PURGE(RCONTAINER => RPROC_PARAMS);
|
||
end EQCONFIG_THOBJ_FORECAST_BCLRAT;
|
||
|
||
/* Подготовка запроса на формирование прогноза технического объекта */
|
||
procedure EQCONFIG_THOBJ_FORECAST_PRLG
|
||
(
|
||
NEQUIPDSCMML in number, -- Рег. номер модели
|
||
NDATASET_IDENT in number, -- Идентификатор буфера данных
|
||
NDATASET_CONFIG_IDENT in number, -- Идентификатор буфера описания данных
|
||
NREQUEST_CONFIG_IDENT in number, -- Идентификатор буфера описания запроса
|
||
SURL out varchar2, -- Адрес для запроса
|
||
SAUTH_TOKEN out varchar2, -- Токен аутентификации для запроса
|
||
SDATASET_ID out varchar2, -- Идентификатор выборки данных запроса
|
||
CDATASET_CONFIG out clob, -- Описание данных о наработках
|
||
SDATASET_URL out varchar2, -- Адрес для получения данных о наработках
|
||
SCLASS_MACHINE out varchar2, -- Код класса оборудования для запроса
|
||
STASK out varchar2 -- Задача для запроса (см. константы UDO_PKG_EQUIPDS_BASE.SCMML_TASK_*)
|
||
)
|
||
is
|
||
REQUIPDSCMML UDO_T_EQUIPDSCMML%rowtype; -- Запись модели
|
||
REQUIPDSCM UDO_T_EQUIPDSCM%rowtype; -- Запись класса оборудования выборки данных, родительской для модели
|
||
REXSSERVICEFN_SEND_RQ EXSSERVICEFN%rowtype; -- Запись функции обмена для обучения модели
|
||
REXSSERVICE_SEND_RQ EXSSERVICE%rowtype; -- Запись сервиса обмена для обучения модели
|
||
REXSSERVICEFN_FRCST_MD EXSSERVICEFN%rowtype; -- Запись функции обмена для публикации сведений о наработке единицы оборудования при получении прогноза
|
||
REXSSERVICE_FRCST_MD EXSSERVICE%rowtype; -- Запись сервиса обмена для публикации сведений о наработке единицы оборудования при получении прогноза
|
||
NAPI_ROOT_INDEX PKG_STD.TNUMBER; -- Символ вхождения корня API в адрес сервера внешней системы
|
||
NCNT PKG_STD.TNUMBER; -- Буфер для количества файлов данных
|
||
begin
|
||
/* Определим адрес сервера приложений */
|
||
SDATASET_URL := GET_OPTIONS_STR(SCODE => 'EXSService_AppServer');
|
||
if (SDATASET_URL is null) then
|
||
P_EXCEPTION(0,
|
||
'В настройках Системы не задан параметр "Адрес сервера приложений (сервисы обмена)" (номер - 1929, код - "EXSService_AppServer").');
|
||
end if;
|
||
/* Проверим данные о наработках */
|
||
begin
|
||
select count(T.RN)
|
||
into NCNT
|
||
from FILE_BUFFER T
|
||
where T.IDENT = NDATASET_IDENT
|
||
and T.BDATA is not null;
|
||
exception
|
||
when others then
|
||
P_EXCEPTION(0, 'Не удалось проверить набор данных о наработках.');
|
||
end;
|
||
if (NCNT > 1) then
|
||
P_EXCEPTION(0, 'Набор данных о наработках определён неоднозначно.');
|
||
end if;
|
||
if (NCNT = 0) then
|
||
P_EXCEPTION(0, 'Набор данных о наработках не определён.');
|
||
end if;
|
||
/* Читаем описание данных о наработках */
|
||
for C in (select T.DATA CDATA from FILE_BUFFER T where T.IDENT = NDATASET_CONFIG_IDENT)
|
||
loop
|
||
if (CDATASET_CONFIG is not null) then
|
||
P_EXCEPTION(0,
|
||
'Описание набора данных о наработках определёно неоднозначно.');
|
||
end if;
|
||
CDATASET_CONFIG := C.CDATA;
|
||
end loop;
|
||
if (CDATASET_CONFIG is null) then
|
||
P_EXCEPTION(0, 'Описание набора данных о наработках не определёно.');
|
||
end if;
|
||
/* Проверим данные конфигурации запроса */
|
||
begin
|
||
select count(T.RN)
|
||
into NCNT
|
||
from FILE_BUFFER T
|
||
where T.IDENT = NREQUEST_CONFIG_IDENT
|
||
and T.BDATA is not null;
|
||
exception
|
||
when others then
|
||
P_EXCEPTION(0,
|
||
'Не удалось проверить параметры запроса на прогнозирование.');
|
||
end;
|
||
if (NCNT > 1) then
|
||
P_EXCEPTION(0,
|
||
'Параметры запроса на прогнозирование определёны неоднозначно.');
|
||
end if;
|
||
if (NCNT = 0) then
|
||
P_EXCEPTION(0,
|
||
'Параметры запроса на прогнозирование не определёны.');
|
||
end if;
|
||
/* Читаем запись модели */
|
||
REQUIPDSCMML := UDO_PKG_EQUIPDS_BASE.CMML_GET(NFLAG_SMART => 0, NRN => NEQUIPDSCMML);
|
||
if (REQUIPDSCMML.STATUS <> UDO_PKG_EQUIPDS_BASE.NCMML_STATUS_PROCESSED) then
|
||
P_EXCEPTION(0,
|
||
'Модель (регистрационный номер %s) находится в состоянии отличном от "Обучена".',
|
||
TO_CHAR(REQUIPDSCMML.RN));
|
||
end if;
|
||
/* Читаем запись её родительского класса оборудования */
|
||
REQUIPDSCM := UDO_PKG_EQUIPDS_BASE.CM_GET(NFLAG_SMART => 0, NRN => REQUIPDSCMML.PRN);
|
||
/* Читаем функию и сервис обмена, применяемые для обучения модели */
|
||
REXSSERVICEFN_SEND_RQ := GET_EXSSERVICEFN_ID(NFLAG_SMART => 0, NRN => REQUIPDSCM.EXSSERVICEFN_SEND_RQ);
|
||
REXSSERVICE_SEND_RQ := GET_EXSSERVICE_ID(NFLAG_SMART => 0, NRN => REXSSERVICEFN_SEND_RQ.PRN);
|
||
/* Формируем URL для запроса */
|
||
NAPI_ROOT_INDEX := INSTR(REXSSERVICE_SEND_RQ.SRV_ROOT, SFW_API_ROOT);
|
||
if (NAPI_ROOT_INDEX = 0) then
|
||
P_EXCEPTION(0,
|
||
'Неожиданный формат адреса внешней системы "%s" - не удалось определить корень API ("%s").',
|
||
REXSSERVICE_SEND_RQ.SRV_ROOT,
|
||
SFW_API_ROOT);
|
||
end if;
|
||
SURL := SUBSTR(REXSSERVICE_SEND_RQ.SRV_ROOT, 1, NAPI_ROOT_INDEX - 1) || SFW_API_ROOT || SFW_API_FORECAST;
|
||
/* Формируем токен для аутентификации */
|
||
SAUTH_TOKEN := TO_CHAR(BASE64_ENCODE(CLOB2BLOB(REXSSERVICE_SEND_RQ.SRV_USER || ':' ||
|
||
BLOB2CLOB(BASE64_DECODE(REXSSERVICE_SEND_RQ.SRV_PASS)))));
|
||
/* Формируем идентификатор выборки данных для запроса (в данном случае - просто уникальный идентификатор выборки, ссылка на которую будет передана в "data_url" с запросом на прогноз) */
|
||
SDATASET_ID := TO_CHAR(NDATASET_IDENT);
|
||
/* Читаем функию и сервис обмена, применяемые для публикации данных наработки модели */
|
||
REXSSERVICEFN_FRCST_MD := GET_EXSSERVICEFN_ID(NFLAG_SMART => 0, NRN => REQUIPDSCM.EXSSERVICEFN_FRCST_MD);
|
||
REXSSERVICE_FRCST_MD := GET_EXSSERVICE_ID(NFLAG_SMART => 0, NRN => REXSSERVICEFN_FRCST_MD.PRN);
|
||
/* Формируем адрес для получения фреймворком данных о наработках (по ним будет строиться прогоз, их мы готовили предварительно, вызовом ПП) */
|
||
if ((SUBSTR(SDATASET_URL, -1) <> '/') and (SUBSTR(REXSSERVICE_FRCST_MD.SRV_ROOT, 1, 1) <> '/')) then
|
||
SDATASET_URL := SDATASET_URL || '/';
|
||
end if;
|
||
SDATASET_URL := SDATASET_URL || REXSSERVICE_FRCST_MD.SRV_ROOT;
|
||
if ((SUBSTR(SDATASET_URL, -1) <> '/') and (SUBSTR(REXSSERVICEFN_FRCST_MD.FN_URL, 1, 1) <> '/')) then
|
||
SDATASET_URL := SDATASET_URL || '/';
|
||
end if;
|
||
SDATASET_URL := SDATASET_URL || REXSSERVICEFN_FRCST_MD.FN_URL || '?NDATASET_IDENT=' || TO_CHAR(NDATASET_IDENT);
|
||
/* Код класса оборудования для запроса */
|
||
begin
|
||
select T.CODE into SCLASS_MACHINE from EQOBJKIND T where T.RN = REQUIPDSCM.EQOBJKIND;
|
||
exception
|
||
when NO_DATA_FOUND then
|
||
PKG_MSG.RECORD_NOT_FOUND(NFLAG_SMART => 0, NDOCUMENT => REQUIPDSCM.EQOBJKIND, SUNIT_TABLE => 'EQOBJKIND');
|
||
end;
|
||
/* Задача для запроса */
|
||
STASK := REQUIPDSCMML.TASK;
|
||
exception
|
||
when others then
|
||
/* Подчистим буферы */
|
||
EQCONFIG_THOBJ_FORECAST_BCLRAT(NDATASET_IDENT => NDATASET_IDENT,
|
||
NDATASET_CONFIG_IDENT => NDATASET_CONFIG_IDENT,
|
||
NREQUEST_CONFIG_IDENT => NREQUEST_CONFIG_IDENT);
|
||
/* Пробросим ошибку */
|
||
raise;
|
||
end EQCONFIG_THOBJ_FORECAST_PRLG;
|
||
|
||
/* Финализация исполнения запроса на формирование прогноза технического объекта */
|
||
procedure EQCONFIG_THOBJ_FORECAST_EPLG
|
||
(
|
||
NDATASET_IDENT in number, -- Идентификатор буфера данных
|
||
NDATASET_CONFIG_IDENT in number, -- Идентификатор буфера описания данных
|
||
NREQUEST_CONFIG_IDENT in number, -- Идентификатор буфера описания запроса
|
||
NEQCONFIG in number, -- Рег. номер технического объекта
|
||
NEQUIPDSCMML in number, -- Рег. номер модели
|
||
CFORECAST in clob -- Данные прогноза
|
||
)
|
||
is
|
||
NEQUIPDSCMMLH PKG_STD.TREF; -- Рег. номер истории запросов модели
|
||
BRQ blob; -- Описание параметров запроса на прогноз
|
||
begin
|
||
/* Считаем параметры сделанного запроса */
|
||
begin
|
||
select T.BDATA
|
||
into BRQ
|
||
from FILE_BUFFER T
|
||
where T.IDENT = NREQUEST_CONFIG_IDENT
|
||
and T.BDATA is not null;
|
||
exception
|
||
when NO_DATA_FOUND then
|
||
P_EXCEPTION(0, 'Параметры запроса на прогнозирование не определёны.');
|
||
when TOO_MANY_ROWS then
|
||
P_EXCEPTION(0, 'Параметры запроса на прогнозирование определёны неоднозначно.');
|
||
end;
|
||
/* Добавляем запись истории запросов */
|
||
UDO_PKG_EQUIPDS_BASE.CMMLH_INS(NPRN => NEQUIPDSCMML,
|
||
NEQCONFIG => NEQCONFIG,
|
||
SRQ_AUTHID => UTILIZER(),
|
||
DRQ_DATE => sysdate,
|
||
BRQ => BRQ,
|
||
NRN => NEQUIPDSCMMLH);
|
||
/* Сохраним данные прогноза */
|
||
UDO_PKG_EQUIPDS_BASE.CMMLH_SET_FORECAST(NRN => NEQUIPDSCMMLH, BFORECAST => BASE64_DECODE(LCSRCE => CFORECAST));
|
||
/* Подчистим буферы */
|
||
EQCONFIG_THOBJ_FORECAST_BCLR(NDATASET_IDENT => NDATASET_IDENT,
|
||
NDATASET_CONFIG_IDENT => NDATASET_CONFIG_IDENT,
|
||
NREQUEST_CONFIG_IDENT => NREQUEST_CONFIG_IDENT);
|
||
exception
|
||
when others then
|
||
/* Подчистим буферы */
|
||
EQCONFIG_THOBJ_FORECAST_BCLRAT(NDATASET_IDENT => NDATASET_IDENT,
|
||
NDATASET_CONFIG_IDENT => NDATASET_CONFIG_IDENT,
|
||
NREQUEST_CONFIG_IDENT => NREQUEST_CONFIG_IDENT);
|
||
/* Пробросим ошибку */
|
||
raise;
|
||
end EQCONFIG_THOBJ_FORECAST_EPLG;
|
||
|
||
/* Формирование цвета прогноза для технического объекта */
|
||
function EQCONFIG_THOBJ_FORECAST_CLR
|
||
(
|
||
NMODE in number := 0, -- Режим работы (0 - для подсказки в колонке таблицы, 1 - для колонки таблицы, 2 - для карточки детализации
|
||
NVALUE in number :=0 -- Значение для подсветки
|
||
) return varchar2 -- Запрошенное значение в зависимости от режима
|
||
is
|
||
begin
|
||
/* Работаем от режима */
|
||
case NMODE
|
||
/* Для подсказки в колонке таблицы */
|
||
when 0 then
|
||
return '<b style="color:red">Опасность</b> - вероятность сбоя более 60%.<br>' || '<b style="color:orange">Внимание</b> - вероятность сбоя от 30% до 60%<br>' || '<b style="color:green">В норме</b> - вероятность сбоев менее 30%';
|
||
/* Для колонки таблицы */
|
||
when 1 then
|
||
begin
|
||
if (NVALUE < 30) then
|
||
return 'success';
|
||
else
|
||
if ((NVALUE >= 30) and (NVALUE < 60)) then
|
||
return 'warning';
|
||
else
|
||
return 'error';
|
||
end if;
|
||
end if;
|
||
end;
|
||
/* Для карточки детализации */
|
||
when 2 then
|
||
begin
|
||
if (NVALUE < 30) then
|
||
return 'success.main';
|
||
else
|
||
if ((NVALUE >= 30) and (NVALUE < 60)) then
|
||
return 'warning.main';
|
||
else
|
||
return 'error.main';
|
||
end if;
|
||
end if;
|
||
end;
|
||
/* Неверный режим */
|
||
else
|
||
return null;
|
||
end case;
|
||
end EQCONFIG_THOBJ_FORECAST_CLR;
|
||
|
||
/* Формирование детальной карточки прогноза для технического объекта */
|
||
procedure EQCONFIG_THOBJ_FORECAST_CRD
|
||
(
|
||
NEQCONFIG in number, -- Рег. номер позиции состава оборудования
|
||
DFORECAST_DATE in date, -- Дата получения прогноза
|
||
NFORECAST in number, -- Прогнозное значение, полученное от фреймворка
|
||
SDICMUNTS in varchar2, -- Единица измерения выборки
|
||
STASK in varchar2, -- Задача (см. константы UDO_PKG_EQUIPDS_BASE.CMML_TASK_*)
|
||
COUT out clob -- Данные детальной карточки прогноза
|
||
)
|
||
is
|
||
NCUR integer; -- Курсор документа для результата
|
||
XDOC PKG_XMAKE.TNODE; -- Документ для результата
|
||
XROOT PKG_XMAKE.TNODE; -- Содержимое корневого узла документа
|
||
RCH PKG_P8PANELS_VISUAL.TCHART; -- График
|
||
RCH_DS PKG_P8PANELS_VISUAL.TCHART_DATASET; -- Набор данных
|
||
CCHART clob; -- Сериализованный график
|
||
NBREAKDOWN_PROB PKG_STD.TNUMBER; -- Вероятность выхода из строя
|
||
NBREAKDOWN_PROB_CUR PKG_STD.TNUMBER; -- Вероятность выхода из строя (для текущей позиции графика ТО и ремонтов/рем. ведомости)
|
||
DNEXT_REPAIR PKG_STD.TLDATE; -- Дата ближайшего ТО и ремонта по графику/рем. ведомости
|
||
begin
|
||
/* Вычислим вероятность выхода из строя до даты ближайшего ТО/ремонта по графику или рем. ведомости с учётом прогноза */
|
||
DNEXT_REPAIR := EQCONFIG_THOBJ_GEN_NXTRPR(NEQCONFIG => NEQCONFIG);
|
||
if (DNEXT_REPAIR is null) then
|
||
NBREAKDOWN_PROB := 100;
|
||
else
|
||
if (sysdate + NFORECAST > DNEXT_REPAIR) then
|
||
NBREAKDOWN_PROB := 0;
|
||
end if;
|
||
end if;
|
||
/* Открываем документ */
|
||
NCUR := PKG_XMAKE.OPEN_CURSOR();
|
||
/* Заполним единицу измерения */
|
||
XROOT := PKG_XMAKE.CONCAT(ICURSOR => NCUR,
|
||
RNODE00 => XROOT,
|
||
RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
|
||
SNAME => 'SDICMUNTS',
|
||
RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => NCUR, SVALUE => SDICMUNTS)));
|
||
/* Заполним прогноз */
|
||
XROOT := PKG_XMAKE.CONCAT(ICURSOR => NCUR,
|
||
RNODE00 => XROOT,
|
||
RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
|
||
SNAME => 'NFORECAST',
|
||
RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => NCUR, NVALUE => NFORECAST)));
|
||
/* Заполним код задачи прогнозирования */
|
||
XROOT := PKG_XMAKE.CONCAT(ICURSOR => NCUR,
|
||
RNODE00 => XROOT,
|
||
RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
|
||
SNAME => 'STASK',
|
||
RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => NCUR, SVALUE => STASK)));
|
||
/* Заполним наименование задачи прогнозирования */
|
||
XROOT := PKG_XMAKE.CONCAT(ICURSOR => NCUR,
|
||
RNODE00 => XROOT,
|
||
RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
|
||
SNAME => 'STASK_NAME',
|
||
RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => NCUR,
|
||
SVALUE => UDO_PKG_EQUIPDS_BASE.CMML_TASK_NAME(STASK => STASK))));
|
||
/* Заполним дату следующего ТО и ремонта */
|
||
XROOT := PKG_XMAKE.CONCAT(ICURSOR => NCUR,
|
||
RNODE00 => XROOT,
|
||
RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
|
||
SNAME => 'DNEXT_REPAIR',
|
||
RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => NCUR,
|
||
DVALUE => DNEXT_REPAIR)));
|
||
/* Если есть запланированные графики ТО и ремонта или ремонтные ведомости */
|
||
if (DNEXT_REPAIR is not null) then
|
||
/* Строим график вероятностей выхода из строя опираясь на них */
|
||
RCH := PKG_P8PANELS_VISUAL.TCHART_MAKE(STYPE => PKG_P8PANELS_VISUAL.SCHART_TYPE_LINE,
|
||
STITLE => 'Прогноз с учётом графика ТО и ремонтов/ремонтных ведомостей',
|
||
SLGND_POS => PKG_P8PANELS_VISUAL.SCHART_LGND_POS_TOP);
|
||
/* Сформируем набор данных */
|
||
RCH_DS := PKG_P8PANELS_VISUAL.TCHART_DATASET_MAKE(SCAPTION => 'Вероятность перехода в критическое состояние (%)');
|
||
/* Обходим ближайшие 5 позиций графика ТО и ремонтов или ремонтных ведомостей */
|
||
for C in (select ROWNUM,
|
||
D.DDATEPRD_BEG
|
||
from (select T.DDATEPRD_BEG
|
||
from (select P.DATEPRD_BEG DDATEPRD_BEG
|
||
from EQTCHSRV P
|
||
where P.EQCONFIG_TECH = NEQCONFIG
|
||
and P.DATEPRD_BEG >= sysdate
|
||
union
|
||
select R.DATEPLAN_BEG DDATEPRD_BEG
|
||
from EQRPSHEETS R
|
||
where R.EQCONFIG = NEQCONFIG
|
||
and R.DATEPLAN_BEG >= sysdate) T
|
||
order by T.DDATEPRD_BEG) D
|
||
where ROWNUM <= 5)
|
||
loop
|
||
/* Добавим метку для графика */
|
||
PKG_P8PANELS_VISUAL.TCHART_ADD_LABEL(RCHART => RCH, SLABEL => TO_CHAR(C.DDATEPRD_BEG, 'dd.mm.yyyy'));
|
||
/* Считаем вероятность выхода из строя в эту дату */
|
||
NBREAKDOWN_PROB_CUR := UDO_PKG_EQUIPDS_BASE.CMML_RUL_BREAKDOWN_PROB(NFORECAST => NFORECAST,
|
||
DFORECAST_DATE => DFORECAST_DATE,
|
||
DDATE => C.DDATEPRD_BEG);
|
||
/* Если ещё не фиксировали вероятность для первой даты - сделаем это */
|
||
if (NBREAKDOWN_PROB is null) then
|
||
NBREAKDOWN_PROB := NBREAKDOWN_PROB_CUR;
|
||
end if;
|
||
/* Добавим элемент в набор данных */
|
||
PKG_P8PANELS_VISUAL.TCHART_DATASET_ADD_ITEM(RDATASET => RCH_DS, NVALUE => NBREAKDOWN_PROB_CUR);
|
||
end loop;
|
||
/* Добавим набор данных в график */
|
||
PKG_P8PANELS_VISUAL.TCHART_ADD_DATASET(RCHART => RCH, RDATASET => RCH_DS);
|
||
/* Сериализуем график */
|
||
CCHART := PKG_P8PANELS_VISUAL.TCHART_TO_XML(RCHART => RCH, NINCLUDE_DEF => 1);
|
||
end if;
|
||
/* Заполним вероятность выхода из стороя до ближайшего ТО с учётом прогноза */
|
||
XROOT := PKG_XMAKE.CONCAT(ICURSOR => NCUR,
|
||
RNODE00 => XROOT,
|
||
RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
|
||
SNAME => 'NBREAKDOWN_PROB',
|
||
RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => NCUR,
|
||
NVALUE => NBREAKDOWN_PROB)));
|
||
/* Заполним цвет вероятности выхода из стороя до ближайшего ТО с учётом прогноза */
|
||
XROOT := PKG_XMAKE.CONCAT(ICURSOR => NCUR,
|
||
RNODE00 => XROOT,
|
||
RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
|
||
SNAME => 'SBREAKDOWN_PROB_COLOR',
|
||
RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => NCUR,
|
||
SVALUE => EQCONFIG_THOBJ_FORECAST_CLR(NMODE => 2,
|
||
NVALUE => NBREAKDOWN_PROB))));
|
||
/* Добавляем график в ответ */
|
||
XROOT := PKG_XMAKE.CONCAT(ICURSOR => NCUR,
|
||
RNODE00 => XROOT,
|
||
RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
|
||
SNAME => 'XCHART',
|
||
RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => NCUR, LCVALUE => CCHART)));
|
||
/* Формируем XML-представление ответа */
|
||
XDOC := PKG_XMAKE.ELEMENT(ICURSOR => NCUR, SNAME => 'XDATA', RNODE00 => XROOT);
|
||
/* Конвертируем в CLOB */
|
||
COUT := PKG_XMAKE.SERIALIZE_TO_CLOB(ICURSOR => NCUR,
|
||
ITYPE => PKG_XMAKE.CONTENT_,
|
||
RNODE => XDOC,
|
||
RHEADER => PKG_XHEADER.WRAP_ALL(SVERSION => PKG_XHEADER.VERSION_1_0_,
|
||
SENCODING => PKG_XHEADER.ENCODING_UTF_,
|
||
SSTANDALONE => PKG_XHEADER.STANDALONE_YES_));
|
||
/* Закрываем документ */
|
||
PKG_XMAKE.CLOSE_CURSOR(ICURSOR => NCUR);
|
||
end EQCONFIG_THOBJ_FORECAST_CRD;
|
||
|
||
/* Извлечение сведений из детальной карточки прогноза для технического объекта */
|
||
procedure EQCONFIG_THOBJ_FORECAST_CRDP
|
||
(
|
||
CFORECAST in clob, -- Данные детальной карточки прогноза
|
||
SFORECAST_DESC out varchar2, -- Описание прогноза
|
||
SFORECAST_DESC_COLOR out varchar2 -- Цвет заливки прогноза
|
||
)
|
||
is
|
||
XDOC PKG_XPATH.TDOCUMENT; -- Десериализованный демо-прогноз
|
||
XROOT PKG_XPATH.TNODE; -- Корневой элемент данных
|
||
SDICMUNTS PKG_STD.TSTRING; -- Единица измерения выборки
|
||
NFORECAST PKG_STD.TNUMBER; -- Прогноз по заданной задаче
|
||
NBREAKDOWN_PROB PKG_STD.TNUMBER; -- Вероятность выхода из строя
|
||
begin
|
||
/* Разбираем демо-даные */
|
||
XDOC := PKG_XPATH.PARSE_FROM_CLOB(LCXML => CFORECAST);
|
||
/* Извлекаем корневой элемент */
|
||
XROOT := PKG_XPATH.ROOT_NODE(RDOCUMENT => XDOC);
|
||
/* Читаем единицу измерения */
|
||
SDICMUNTS := PKG_XPATH.VALUE(RNODE => PKG_XPATH.SINGLE_NODE(RPARENT_NODE => XROOT, SPATTERN => 'XDATA/SDICMUNTS'));
|
||
/* Читаем прогноз */
|
||
NFORECAST := PKG_XPATH.VALUE_NUM(RNODE => PKG_XPATH.SINGLE_NODE(RPARENT_NODE => XROOT, SPATTERN => 'XDATA/NFORECAST'));
|
||
/* Читаем вероятность выхода из строя */
|
||
NBREAKDOWN_PROB := PKG_XPATH.VALUE_NUM(RNODE => PKG_XPATH.SINGLE_NODE(RPARENT_NODE => XROOT,
|
||
SPATTERN => 'XDATA/NBREAKDOWN_PROB'));
|
||
/* Проноз есть */
|
||
if (NFORECAST is not null) then
|
||
/* Возвращаем значение описания */
|
||
SFORECAST_DESC := TO_CHAR(ROUND(NFORECAST)) || SDICMUNTS || ' / ' || TO_CHAR(ROUND(NBREAKDOWN_PROB)) || '%';
|
||
/* Возвращаем значение цвета заливки описания прогноза */
|
||
SFORECAST_DESC_COLOR := EQCONFIG_THOBJ_FORECAST_CLR(NMODE => 1, NVALUE => NBREAKDOWN_PROB);
|
||
end if;
|
||
exception
|
||
when others then
|
||
null;
|
||
end EQCONFIG_THOBJ_FORECAST_CRDP;
|
||
|
||
/* Вероятность выхода единицы оборудования из строя с учётом графика ТО и ремонтов и RUL-прогноза */
|
||
function EQCONFIG_THOBJ_TCHSRV_BRKDPROB
|
||
(
|
||
NEQCONFIG in number -- Рег. номер технического объекта
|
||
) return number -- Вероятность выхода из строя
|
||
is
|
||
NRES PKG_STD.TNUMBER; -- Буфер для результата
|
||
DFORECAST_DATE PKG_STD.TLDATE; -- Дата прогноза
|
||
NFORECAST PKG_STD.TNUMBER; -- Значение самго свежего прогноза модели
|
||
DCALC_DATE PKG_STD.TLDATE; -- Дата расчета вероятности
|
||
begin
|
||
/* Определим дату ближайшего ТО или ремонта */
|
||
DCALC_DATE := EQCONFIG_THOBJ_GEN_NXTRPR(NEQCONFIG => NEQCONFIG);
|
||
/* Если дата есть */
|
||
if (DCALC_DATE is not null) then
|
||
/* Вынем самый свежий прогноз */
|
||
for C in (select T.RQ_DATE DFORECAST_DATE,
|
||
T.FORECAST
|
||
from UDO_T_EQUIPDSCMMLH T,
|
||
UDO_T_EQUIPDSCMML CMML
|
||
where T.EQCONFIG = NEQCONFIG
|
||
and T.PRN = CMML.RN
|
||
and CMML.TASK = UDO_PKG_EQUIPDS_BASE.SCMML_TASK_RUL
|
||
order by T.RQ_DATE desc)
|
||
loop
|
||
DFORECAST_DATE := C.DFORECAST_DATE;
|
||
UDO_PKG_EQUIPDS.CMMLH_PARSE_FORECAST(CFORECAST => BLOB2CLOB(LBDATA => C.FORECAST), NFORECAST => NFORECAST);
|
||
exit;
|
||
end loop;
|
||
/* Если есть и прогноз */
|
||
if (NFORECAST is not null) then
|
||
NRES := UDO_PKG_EQUIPDS_BASE.CMML_RUL_BREAKDOWN_PROB(NFORECAST => NFORECAST,
|
||
DFORECAST_DATE => DFORECAST_DATE,
|
||
DDATE => DCALC_DATE);
|
||
end if;
|
||
end if;
|
||
/* Вернём то, что собрали */
|
||
return NRES;
|
||
end EQCONFIG_THOBJ_TCHSRV_BRKDPROB;
|
||
|
||
/* Модификация графика ТО и ремонтов для технического объекта */
|
||
procedure EQCONFIG_THOBJ_CHNG_EQTCHSRV
|
||
(
|
||
NEQCONFIG in number, -- Рег. номер технического объекта
|
||
NEQTCHSRV in number, -- Рег. номер графика ТО и ремонтов
|
||
DPLANDATE_FROM in date -- Уточнённая плановая дата начала ремонта
|
||
)
|
||
is
|
||
REQTCHSRV EQTCHSRV%rowtype; -- Запись графика ТО и ремонтов
|
||
RDSCMMLH UDO_T_EQUIPDSCMMLH%rowtype; -- Запись истории прогнозов
|
||
NDIFF PKG_STD.TNUMBER; -- Отклонение старой и новой дат
|
||
DDATEPRD_BEG PKG_STD.TLDATE; -- Новая дата начала
|
||
DDATEPRD_END PKG_STD.TLDATE; -- Новая дата окончания
|
||
SNOTE PKG_STD.TSTRING; -- Новое примечание
|
||
begin
|
||
/* Считаем график */
|
||
begin
|
||
select T.* into REQTCHSRV from EQTCHSRV T where T.RN = NEQTCHSRV;
|
||
exception
|
||
when NO_DATA_FOUND then
|
||
PKG_MSG.RECORD_NOT_FOUND(NFLAG_SMART => 0, NDOCUMENT => NEQTCHSRV, SUNIT_TABLE => 'EquipTechServices');
|
||
end;
|
||
/* Считаем запись истории прогнозов */
|
||
begin
|
||
select T.*
|
||
into RDSCMMLH
|
||
from UDO_T_EQUIPDSCMMLH T
|
||
where T.RN = (select max(TT.RN) from UDO_T_EQUIPDSCMMLH TT where TT.EQCONFIG = NEQCONFIG);
|
||
exception
|
||
when others then
|
||
P_EXCEPTION(0,
|
||
'Не удалось определить запись-основание истории прогнозов модели.');
|
||
end;
|
||
/* Проверим, что из графика не сформирована ремонтная ведомость */
|
||
if (F_DOCLINKS_LINK_OUT_DOC(SIN_UNITCODE => 'EquipTechServices',
|
||
NIN_DOCUMENT => REQTCHSRV.RN,
|
||
SOUT_UNITCODE => 'EquipRepairSheets') is not null) then
|
||
P_EXCEPTION(0,
|
||
'Из графика ТО и ремонтов (RN: %s) уже создана ремонтная ведомость.',
|
||
TO_CHAR(REQTCHSRV.RN));
|
||
end if;
|
||
/* Проверим, что есть на что менять */
|
||
if (TRUNC(DPLANDATE_FROM) = TRUNC(REQTCHSRV.DATEPRD_BEG)) then
|
||
P_EXCEPTION(0,
|
||
'Выбранный график ТО и ремонтов уже запланирован на %s',
|
||
TO_CHAR(DPLANDATE_FROM, 'dd.mm.yyyy'));
|
||
end if;
|
||
/* Сбросим состояние графика */
|
||
if (REQTCHSRV.STATE <> 0) then
|
||
P_EQTCHSRV_SET_STATE(NCOMPANY => REQTCHSRV.COMPANY, NRN => REQTCHSRV.RN, NSTATE => 0, DDATE => sysdate);
|
||
end if;
|
||
/* Определим отклонение и новые даты графика */
|
||
NDIFF := DPLANDATE_FROM - REQTCHSRV.DATEPRD_BEG;
|
||
DDATEPRD_BEG := REQTCHSRV.DATEPRD_BEG + NDIFF;
|
||
DDATEPRD_END := REQTCHSRV.DATEPRD_END + NDIFF;
|
||
/* Формируем новое примечание */
|
||
SNOTE := 'Автоматически перенесён с "' || TO_CHAR(REQTCHSRV.DATEPRD_BEG, 'dd.mm.yyyy hh24:mi:ss') || '" на "' ||
|
||
TO_CHAR(DDATEPRD_BEG, 'dd.mm.yyyy hh24:mi:ss') || '" на основании прогноза от "' ||
|
||
TO_CHAR(RDSCMMLH.RQ_DATE, 'dd.mm.yyyy hh24:mi:ss') || '" (RN: ' || TO_CHAR(RDSCMMLH.RN) ||
|
||
', пользователь: ' || RDSCMMLH.RQ_AUTHID || ').';
|
||
/* Изменим заголовок графика */
|
||
update EQTCHSRV T
|
||
set T.DATEPRD_BEG = DDATEPRD_BEG,
|
||
T.DATEPRD_END = DDATEPRD_END,
|
||
T.NOTE = SNOTE
|
||
where T.RN = REQTCHSRV.RN;
|
||
/* Сдвинем работы */
|
||
P_EQTCHSRV_MOVE_WORK(NCOMPANY => REQTCHSRV.COMPANY,
|
||
NRN => REQTCHSRV.RN,
|
||
NDUP_RN => null,
|
||
DDATEPRD_BEG => DDATEPRD_BEG,
|
||
DOLD_DATEPRD_BEG => REQTCHSRV.DATEPRD_BEG,
|
||
DDATEPRD_END => DDATEPRD_END,
|
||
NPERIOD => null,
|
||
NMODE => 1);
|
||
/* Восстановим состояние графика */
|
||
if (REQTCHSRV.STATE <> 0) then
|
||
P_EQTCHSRV_SET_STATE(NCOMPANY => REQTCHSRV.COMPANY,
|
||
NRN => REQTCHSRV.RN,
|
||
NSTATE => REQTCHSRV.STATE,
|
||
DDATE => sysdate);
|
||
end if;
|
||
end EQCONFIG_THOBJ_CHNG_EQTCHSRV;
|
||
|
||
/* Формирование ремонтной ведомости для технического объекта */
|
||
procedure EQCONFIG_THOBJ_MAKE_EQRPSHEET
|
||
(
|
||
NEQCONFIG in number, -- Рег. номер технического объекта
|
||
SACATALOG in varchar2, -- Каталог размещения ведомости
|
||
SEQTECSRVKIND in varchar2, -- Вид ремонта
|
||
DPLANDATE_FROM in date, -- Плановая дата начала ремонта
|
||
NIDENT out number -- Идентификатор списка сформированных ведомостей
|
||
|
||
)
|
||
is
|
||
NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Рег. номер организации
|
||
NCRN PKG_STD.TREF; -- Рег. номер каталога размещения ведомости
|
||
SJURPERSONS PKG_STD.TSTRING; -- Юридическая принадлежность технического объекта
|
||
SCURRENCY PKG_STD.TSTRING; -- Валюта ведомости
|
||
SDOCTYPES PKG_STD.TSTRING; -- Тип документа ведомости
|
||
SPREF PKG_STD.TSTRING; -- Префикс ведосмости
|
||
SNUMB PKG_STD.TSTRING; -- Номер ведомости
|
||
NEQRPSHEET PKG_STD.TREF; -- Рег. номер сформированной ведомости
|
||
begin
|
||
/* Определяем юридическую принадлежность технического объекта */
|
||
begin
|
||
select JP.CODE
|
||
into SJURPERSONS
|
||
from EQCONFIG T,
|
||
JURPERSONS JP
|
||
where T.RN = NEQCONFIG
|
||
and T.JUR_PERS = JP.RN;
|
||
exception
|
||
when NO_DATA_FOUND then
|
||
PKG_MSG.RECORD_NOT_FOUND(NFLAG_SMART => 0, NDOCUMENT => NEQCONFIG, SUNIT_TABLE => 'EquipConfiguration');
|
||
end;
|
||
/* Читаем валюту документа по-умолчанию из параметров */
|
||
SCURRENCY := GET_OPTIONS_STR(SCODE => 'Equip_RepairSheets_Currency');
|
||
/* Читаем тип документа по-умолчанию из параметров */
|
||
SDOCTYPES := GET_OPTIONS_STR(SCODE => 'Equip_RepairSheets_DocType');
|
||
/* Читаем префикс документа по-умолчанию из параметров */
|
||
SPREF := GET_OPTIONS_STR(SCODE => 'Equip_RepairSheets_DocPref');
|
||
/* Формируем очередной номер документа */
|
||
P_EQRPSHEETS_GETNEXTNUMB(NCOMPANY => NCOMPANY, SPREF => SPREF, SDOCTYPES => SDOCTYPES, SNUMB => SNUMB);
|
||
/* Определяем каталог размещения */
|
||
FIND_ACATALOG_NAME(NFLAG_SMART => 0,
|
||
NCOMPANY => NCOMPANY,
|
||
NVERSION => null,
|
||
SUNITCODE => 'EquipRepairSheets',
|
||
SNAME => SACATALOG,
|
||
NRN => NCRN);
|
||
/* Формируем ведомость */
|
||
P_EQRPSHEETS_MAKE_EQRPSHEET(NCOMPANY => NCOMPANY,
|
||
NCRN => NCRN,
|
||
SDOCTYPES => SDOCTYPES,
|
||
SPREF => SPREF,
|
||
SNUMB => SNUMB,
|
||
DDOCDATE => sysdate,
|
||
SJURPERSONS => SJURPERSONS,
|
||
DPLANDATE_FROM => DPLANDATE_FROM,
|
||
DPLANDATE_TO => DPLANDATE_FROM,
|
||
SCURRENCY => SCURRENCY,
|
||
NCOURSE => 1,
|
||
SEQTECSRVKIND => SEQTECSRVKIND,
|
||
NPR_OBJ => null,
|
||
NTECH_OBJ => NEQCONFIG,
|
||
STECH_SRV_DIV => null,
|
||
SRESP_DIV => null,
|
||
SPERF_DIV => null,
|
||
SPERFORM_AGN => null,
|
||
SLEVEL => null,
|
||
SEQOBJKIND => null,
|
||
NRN => NEQRPSHEET);
|
||
/* Добавим ведомость в список */
|
||
EQCONFIG_THOBJ_SELECT_EQRPSHT(NEQRPSHEETS => NEQRPSHEET, NIDENT => NIDENT);
|
||
end EQCONFIG_THOBJ_MAKE_EQRPSHEET;
|
||
|
||
end UDO_PKG_EQUIPTCF;
|
||
/
|