Интерпретация прогноза - разбор реальных данных от фреймворка
This commit is contained in:
parent
c9015e3d16
commit
07976cbe82
@ -191,11 +191,23 @@ create or replace package UDO_PKG_EQUIPDS as
|
|||||||
COUT out clob -- Сериализованная таблица данных
|
COUT out clob -- Сериализованная таблица данных
|
||||||
);
|
);
|
||||||
|
|
||||||
/* Извлечение описания из данных прогноза "Выборки данных оборудования (классы оборудования, модели, история запросов)" */
|
/* Цвет прогноза "Выборки данных оборудования (классы оборудования, модели, история запросов)" */
|
||||||
procedure CMMLH_PARSE_FORECAST
|
function CMMLH_FORECAST_COLOR
|
||||||
(
|
(
|
||||||
CFORECAST in clob, -- Данные прогноза
|
NMODE in number := 0, -- Режим работы (0 - для подсказки в колонке таблицы, 1 - для колонки таблицы, 2 - для карточки детализации
|
||||||
NFORECAST out number -- Значение прогноза
|
NVALUE in number :=0 -- Значение для подсветки
|
||||||
|
) return varchar2; -- Запрошенное значение в зависимости от режима
|
||||||
|
|
||||||
|
/* Карточка прогноза "Выборки данных оборудования (классы оборудования, модели, история запросов)" */
|
||||||
|
procedure CMMLH_FORECAST_CARD
|
||||||
|
(
|
||||||
|
NEQUIPDSCMMLH in number, -- Рег. номер записи истории запросов модели
|
||||||
|
DFORECAST_DATE in date, -- Дата получения прогноза
|
||||||
|
NFORECAST_DAYS in number, -- Прогнозное количество дней до выхода из строя (на дату прогноза)
|
||||||
|
STASK in varchar2, -- Задача (см. константы UDO_PKG_EQUIPDS_BASE.CMML_TASK_*)
|
||||||
|
SFORECAST_DESC out varchar2, -- Краткое описание прогноза
|
||||||
|
SFORECAST_DESC_COLOR out varchar2, -- Цвет заливки прогноза
|
||||||
|
CFORECAST out clob -- Данные детальной карточки прогноза
|
||||||
);
|
);
|
||||||
|
|
||||||
/* Список "Выборки данных оборудования (классы оборудования, модели, история запросов)" по единице оборудования */
|
/* Список "Выборки данных оборудования (классы оборудования, модели, история запросов)" по единице оборудования */
|
||||||
@ -1480,26 +1492,228 @@ create or replace package body UDO_PKG_EQUIPDS as
|
|||||||
COUT := PKG_P8PANELS_VISUAL.TDG_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => 1);
|
COUT := PKG_P8PANELS_VISUAL.TDG_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => 1);
|
||||||
end CMML_LIST_BY_EQCONFIG;
|
end CMML_LIST_BY_EQCONFIG;
|
||||||
|
|
||||||
/* Извлечение описания из данных прогноза "Выборки данных оборудования (классы оборудования, модели, история запросов)" */
|
/* Цвет прогноза "Выборки данных оборудования (классы оборудования, модели, история запросов)" */
|
||||||
procedure CMMLH_PARSE_FORECAST
|
function CMMLH_FORECAST_COLOR
|
||||||
(
|
(
|
||||||
CFORECAST in clob, -- Данные прогноза
|
NMODE in number := 0, -- Режим работы (0 - для подсказки в колонке таблицы, 1 - для колонки таблицы, 2 - для карточки детализации
|
||||||
NFORECAST out number -- Значение прогноза
|
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 CMMLH_FORECAST_COLOR;
|
||||||
|
|
||||||
|
/* Карточка прогноза "Выборки данных оборудования (классы оборудования, модели, история запросов)" */
|
||||||
|
procedure CMMLH_FORECAST_CARD
|
||||||
|
(
|
||||||
|
NEQUIPDSCMMLH in number, -- Рег. номер записи истории запросов модели
|
||||||
|
DFORECAST_DATE in date, -- Дата получения прогноза
|
||||||
|
NFORECAST_DAYS in number, -- Прогнозное количество дней до выхода из строя (на дату прогноза)
|
||||||
|
STASK in varchar2, -- Задача (см. константы UDO_PKG_EQUIPDS_BASE.CMML_TASK_*)
|
||||||
|
SFORECAST_DESC out varchar2, -- Краткое описание прогноза
|
||||||
|
SFORECAST_DESC_COLOR out varchar2, -- Цвет заливки прогноза
|
||||||
|
CFORECAST out clob -- Данные детальной карточки прогноза
|
||||||
)
|
)
|
||||||
is
|
is
|
||||||
XDOC PKG_XPATH.TDOCUMENT; -- Десериализованный демо-прогноз
|
RCMMLH UDO_T_EQUIPDSCMMLH%rowtype; -- Запись истории запросов модели
|
||||||
XROOT PKG_XPATH.TNODE; -- Корневой элемент данных
|
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; -- Дата ближайшего ТО и ремонта по графику/рем. ведомости
|
||||||
|
NFORECAST_DAYS_NOW PKG_STD.TNUMBER; -- Количество дней до выхода из строя согласно прогнозу, но от текущей даты
|
||||||
begin
|
begin
|
||||||
/* Разбираем демо-даные */
|
/* Считаем запись истории запросов к модели */
|
||||||
XDOC := PKG_XPATH.PARSE_FROM_CLOB(LCXML => CFORECAST);
|
RCMMLH := UDO_PKG_EQUIPDS_BASE.CMMLH_GET(NFLAG_SMART => 0, NRN => NEQUIPDSCMMLH);
|
||||||
/* Извлекаем корневой элемент */
|
/* Проноз есть */
|
||||||
XROOT := PKG_XPATH.ROOT_NODE(RDOCUMENT => XDOC);
|
if ((DFORECAST_DATE is not null) and (NFORECAST_DAYS is not null)) then
|
||||||
/* Читаем прогноз */
|
/* Вычислим сколько осталось до выхода из строя от текущей даты */
|
||||||
NFORECAST := PKG_XPATH.VALUE_NUM(RNODE => PKG_XPATH.SINGLE_NODE(RPARENT_NODE => XROOT, SPATTERN => 'XDATA/NFORECAST'));
|
NFORECAST_DAYS_NOW := UDO_PKG_EQUIPDS_BASE.CMMLH_FORECAST_DAYS_NOW(DFORECAST_DATE => DFORECAST_DATE,
|
||||||
exception
|
NFORECAST_DAYS => NFORECAST_DAYS);
|
||||||
when others then
|
/* Вычислим вероятность выхода из строя до даты ближайшего ТО/ремонта по графику или рем. ведомости с учётом прогноза */
|
||||||
null;
|
DNEXT_REPAIR := UDO_PKG_EQUIPTCF.EQCONFIG_THOBJ_GEN_NXTRPR(NEQCONFIG => RCMMLH.EQCONFIG);
|
||||||
end CMMLH_PARSE_FORECAST;
|
NBREAKDOWN_PROB := UDO_PKG_EQUIPDS_BASE.CMMLH_RUL_BREAKDOWN_PROB(DFORECAST_DATE => DFORECAST_DATE,
|
||||||
|
NFORECAST_DAYS => NFORECAST_DAYS,
|
||||||
|
DDATE => DNEXT_REPAIR);
|
||||||
|
/* Открываем документ */
|
||||||
|
NCUR := PKG_XMAKE.OPEN_CURSOR();
|
||||||
|
/* Заполним дату прогноза */
|
||||||
|
XROOT := PKG_XMAKE.CONCAT(ICURSOR => NCUR,
|
||||||
|
RNODE00 => XROOT,
|
||||||
|
RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
|
||||||
|
SNAME => 'SFORECAST_DATE',
|
||||||
|
RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => NCUR,
|
||||||
|
SVALUE => TO_CHAR(DFORECAST_DATE,
|
||||||
|
'dd.mm.yyyy'))));
|
||||||
|
/* Заполним прогнозное количество дней до выхода из стороя на эту дату */
|
||||||
|
XROOT := PKG_XMAKE.CONCAT(ICURSOR => NCUR,
|
||||||
|
RNODE00 => XROOT,
|
||||||
|
RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
|
||||||
|
SNAME => 'NFORECAST_DAYS',
|
||||||
|
RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => NCUR,
|
||||||
|
NVALUE => NFORECAST_DAYS)));
|
||||||
|
/* Заполним прогнозную дату выхода из стороя */
|
||||||
|
XROOT := PKG_XMAKE.CONCAT(ICURSOR => NCUR,
|
||||||
|
RNODE00 => XROOT,
|
||||||
|
RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
|
||||||
|
SNAME => 'SFORECAST_DATE_CALC',
|
||||||
|
RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => NCUR,
|
||||||
|
SVALUE => TO_CHAR(DFORECAST_DATE +
|
||||||
|
NFORECAST_DAYS,
|
||||||
|
'dd.mm.yyyy'))));
|
||||||
|
/* Заполним текущую дату */
|
||||||
|
XROOT := PKG_XMAKE.CONCAT(ICURSOR => NCUR,
|
||||||
|
RNODE00 => XROOT,
|
||||||
|
RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
|
||||||
|
SNAME => 'SFORECAST_DATE_NOW',
|
||||||
|
RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => NCUR,
|
||||||
|
SVALUE => TO_CHAR(sysdate,
|
||||||
|
'dd.mm.yyyy'))));
|
||||||
|
/* Заполним прогнозное количество дней до выхода из стороя на текущую дату */
|
||||||
|
XROOT := PKG_XMAKE.CONCAT(ICURSOR => NCUR,
|
||||||
|
RNODE00 => XROOT,
|
||||||
|
RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
|
||||||
|
SNAME => 'NFORECAST_DAYS_NOW',
|
||||||
|
RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => NCUR,
|
||||||
|
NVALUE => NFORECAST_DAYS_NOW)));
|
||||||
|
/* Заполним код задачи прогнозирования */
|
||||||
|
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 = RCMMLH.EQCONFIG
|
||||||
|
and P.DATEPRD_BEG >= sysdate
|
||||||
|
union
|
||||||
|
select R.DATEPLAN_BEG DDATEPRD_BEG
|
||||||
|
from EQRPSHEETS R
|
||||||
|
where R.EQCONFIG = RCMMLH.EQCONFIG
|
||||||
|
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.CMMLH_RUL_BREAKDOWN_PROB(DFORECAST_DATE => DFORECAST_DATE,
|
||||||
|
NFORECAST_DAYS => NFORECAST_DAYS,
|
||||||
|
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 => CMMLH_FORECAST_COLOR(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 */
|
||||||
|
CFORECAST := 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);
|
||||||
|
/* Возвращаем значение краткого описания прогноза */
|
||||||
|
SFORECAST_DESC := TO_CHAR(NFORECAST_DAYS_NOW) || 'Д / ' || TO_CHAR(ROUND(NBREAKDOWN_PROB)) || '%';
|
||||||
|
/* Возвращаем значение цвета заливки описания прогноза */
|
||||||
|
SFORECAST_DESC_COLOR := CMMLH_FORECAST_COLOR(NMODE => 1, NVALUE => NBREAKDOWN_PROB);
|
||||||
|
end if;
|
||||||
|
end CMMLH_FORECAST_CARD;
|
||||||
|
|
||||||
/* Список "Выборки данных оборудования (классы оборудования, модели, история запросов)" по единице оборудования */
|
/* Список "Выборки данных оборудования (классы оборудования, модели, история запросов)" по единице оборудования */
|
||||||
procedure CMMLH_LIST_BY_EQCONFIG
|
procedure CMMLH_LIST_BY_EQCONFIG
|
||||||
@ -1544,11 +1758,10 @@ create or replace package body UDO_PKG_EQUIPDS as
|
|||||||
SNAME => 'STO_FORECAST_DESC',
|
SNAME => 'STO_FORECAST_DESC',
|
||||||
SCAPTION => 'Прогноз',
|
SCAPTION => 'Прогноз',
|
||||||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
|
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
|
||||||
SHINT => '<b>Формат прогноза:</b> "XXЕИ / YY%", где<br>' ||
|
SHINT => '<b>Формат прогноза:</b> "XXД / YY%", где<br>' ||
|
||||||
'<b>XXЕИ</b> - время до перехода в критическое состояние в ЕИ ресурса единицы оборудования (часы/дни/месяцы/рабочие циклы и т.п.)<br>' ||
|
'<b>XXД</b> - время (в днях, от текущей даты) до перехода в критическое состояние<br>' ||
|
||||||
'<b>YY%</b> - вероятность перехода в критическое состояние до следующего ТО и ремонта<br><br>' ||
|
'<b>YY%</b> - вероятность перехода в критическое состояние до следующего ТО и ремонта<br><br>' ||
|
||||||
'<b>Цвет прогноза:</b><br>' ||
|
'<b>Цвет прогноза:</b><br>' || CMMLH_FORECAST_COLOR(NMODE => 0));
|
||||||
UDO_PKG_EQUIPTCF.EQCONFIG_THOBJ_FORECAST_CLR(NMODE => 0));
|
|
||||||
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
|
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
|
||||||
SNAME => 'STO_FORECAST_DESC_COLOR',
|
SNAME => 'STO_FORECAST_DESC_COLOR',
|
||||||
SCAPTION => 'Цвет прогноза',
|
SCAPTION => 'Цвет прогноза',
|
||||||
@ -1574,7 +1787,8 @@ create or replace package body UDO_PKG_EQUIPDS as
|
|||||||
ML.PRECISION NEQUIPDSCMML_PRECISION,
|
ML.PRECISION NEQUIPDSCMML_PRECISION,
|
||||||
DM.MEAS_MNEMO SDICMUNTS,
|
DM.MEAS_MNEMO SDICMUNTS,
|
||||||
T.FORECAST BFORECAST,
|
T.FORECAST BFORECAST,
|
||||||
null NFORECAST,
|
T.FORECAST_DATE DFORECAST_DATE,
|
||||||
|
T.FORECAST_DAYS NFORECAST_DAYS,
|
||||||
null STO_FORECAST_DESC,
|
null STO_FORECAST_DESC,
|
||||||
null STO_FORECAST_DESC_COLOR,
|
null STO_FORECAST_DESC_COLOR,
|
||||||
null STO_FORECAST
|
null STO_FORECAST
|
||||||
@ -1590,19 +1804,14 @@ create or replace package body UDO_PKG_EQUIPDS as
|
|||||||
and CM.DICMUNTS = DM.RN
|
and CM.DICMUNTS = DM.RN
|
||||||
order by T.RN desc)
|
order by T.RN desc)
|
||||||
loop
|
loop
|
||||||
/* Извлекаем данные из прогноза фреймворка */
|
|
||||||
CMMLH_PARSE_FORECAST(CFORECAST => BLOB2CLOB(LBDATA => C.BFORECAST), NFORECAST => C.NFORECAST);
|
|
||||||
/* Формируем данные карточки прогноза для конкретного тех. объекта */
|
/* Формируем данные карточки прогноза для конкретного тех. объекта */
|
||||||
UDO_PKG_EQUIPTCF.EQCONFIG_THOBJ_FORECAST_CRD(NEQCONFIG => NEQCONFIG,
|
CMMLH_FORECAST_CARD(NEQUIPDSCMMLH => C.NRN,
|
||||||
DFORECAST_DATE => C.DRQ_DATE,
|
DFORECAST_DATE => C.DFORECAST_DATE,
|
||||||
NFORECAST => C.NFORECAST,
|
NFORECAST_DAYS => C.NFORECAST_DAYS,
|
||||||
SDICMUNTS => C.SDICMUNTS,
|
|
||||||
STASK => C.SEQUIPDSCMML_TASK,
|
STASK => C.SEQUIPDSCMML_TASK,
|
||||||
COUT => C.STO_FORECAST);
|
|
||||||
/* Извлекаем прогноз и цвет для видимой колонки таблицы из карточки прогноза для конкретного тех. объекта */
|
|
||||||
UDO_PKG_EQUIPTCF.EQCONFIG_THOBJ_FORECAST_CRDP(CFORECAST => C.STO_FORECAST,
|
|
||||||
SFORECAST_DESC => C.STO_FORECAST_DESC,
|
SFORECAST_DESC => C.STO_FORECAST_DESC,
|
||||||
SFORECAST_DESC_COLOR => C.STO_FORECAST_DESC_COLOR);
|
SFORECAST_DESC_COLOR => C.STO_FORECAST_DESC_COLOR,
|
||||||
|
CFORECAST => C.STO_FORECAST);
|
||||||
/* Добавляем колонки с данными */
|
/* Добавляем колонки с данными */
|
||||||
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NRN', NVALUE => C.NRN, BCLEAR => true);
|
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NRN', NVALUE => C.NRN, BCLEAR => true);
|
||||||
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SRQ_AUTHID', SVALUE => C.SRQ_AUTHID);
|
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SRQ_AUTHID', SVALUE => C.SRQ_AUTHID);
|
||||||
|
@ -44,6 +44,24 @@ create or replace package UDO_PKG_EQUIPDS_BASE as
|
|||||||
DDATASET_TS in date -- Время формирования данных
|
DDATASET_TS in date -- Время формирования данных
|
||||||
) return varchar2; -- Наименование выборки
|
) return varchar2; -- Наименование выборки
|
||||||
|
|
||||||
|
/* Сериализация описания параметров выборки для прогноза */
|
||||||
|
procedure UTL_FORECAST_RQ_MAKE_CFG
|
||||||
|
(
|
||||||
|
DBEG in date, -- Дата "С"
|
||||||
|
DEND in date, -- Дата "По"
|
||||||
|
NINTERVAL in number, -- Длина интервала (в днях, если меньше дня, то дробное - 1/24 для часа, например)
|
||||||
|
CRQ_CFG out clob -- Сериализованное описание параметров выборки для прогноза
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Десериализация описания параметров выборки для прогноза */
|
||||||
|
procedure UTL_FORECAST_RQ_PARSE_CFG
|
||||||
|
(
|
||||||
|
CRQ_CFG in clob, -- Сериализованное описание параметров выборки для прогноза
|
||||||
|
DBEG out date, -- Дата "С"
|
||||||
|
DEND out date, -- Дата "По"
|
||||||
|
NINTERVAL out number -- Длина интервала (в днях, если меньше дня, то дробное - 1/24 для часа, например)
|
||||||
|
);
|
||||||
|
|
||||||
/* Считывание записи "Выборки данных оборудования" по регистрационному номеру */
|
/* Считывание записи "Выборки данных оборудования" по регистрационному номеру */
|
||||||
function GET
|
function GET
|
||||||
(
|
(
|
||||||
@ -293,13 +311,12 @@ create or replace package UDO_PKG_EQUIPDS_BASE as
|
|||||||
function CMML_USERPROCS_FRCST_DATA_HINT
|
function CMML_USERPROCS_FRCST_DATA_HINT
|
||||||
return varchar2; -- Подсказка для процедуры формирования данных для прогноза
|
return varchar2; -- Подсказка для процедуры формирования данных для прогноза
|
||||||
|
|
||||||
/* Вычисление вероятности выхода из строя на дату по RUL-прогнозу */
|
/* Считывание записи "Выборки данных оборудования (классы оборудования, модели, история запросов)" по регистрационному номеру */
|
||||||
function CMML_RUL_BREAKDOWN_PROB
|
function CMMLH_GET
|
||||||
(
|
(
|
||||||
NFORECAST in number, -- RUL-прогноз (интервалов до перехода в предельное состояние)
|
NFLAG_SMART in number, -- Признак выдачи сообщения об ошибке (0 - выдавать, 1 - не выдавать)
|
||||||
DFORECAST_DATE in date, -- Дата прогноза
|
NRN in number -- Регистрационный номер
|
||||||
DDATE in date -- Дата на
|
) return UDO_T_EQUIPDSCMMLH%rowtype; -- Запись итории прогонозов модели
|
||||||
) return number; -- Значение вероятности
|
|
||||||
|
|
||||||
/* Базовое добавление "Выборки данных оборудования (классы оборудования, модели, история запросов)" */
|
/* Базовое добавление "Выборки данных оборудования (классы оборудования, модели, история запросов)" */
|
||||||
procedure CMMLH_INS
|
procedure CMMLH_INS
|
||||||
@ -322,9 +339,27 @@ create or replace package UDO_PKG_EQUIPDS_BASE as
|
|||||||
procedure CMMLH_SET_FORECAST
|
procedure CMMLH_SET_FORECAST
|
||||||
(
|
(
|
||||||
NRN in number, -- Регистрационный номер
|
NRN in number, -- Регистрационный номер
|
||||||
BFORECAST in blob -- Данные прогноза
|
BFORECAST in blob, -- Данные прогноза
|
||||||
|
DFORECAST_DATE in date, -- Дата прогноза
|
||||||
|
NFORECAST_DAYS in number -- Прогноз (дней до выхода из строя на дату прогноза)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/* Вычисление количества дней до выхода из строя от даты */
|
||||||
|
function CMMLH_FORECAST_DAYS_NOW
|
||||||
|
(
|
||||||
|
DFORECAST_DATE in date, -- Дата прогноза
|
||||||
|
NFORECAST_DAYS in number, -- RUL-прогноз (дней до перехода в предельное состояние от даты прогноза)
|
||||||
|
DDATE in date := sysdate -- Дата (не задана - текущая)
|
||||||
|
) return number; -- Количество дней до выхода из строя
|
||||||
|
|
||||||
|
/* Вычисление вероятности выхода из строя на дату по RUL-прогнозу */
|
||||||
|
function CMMLH_RUL_BREAKDOWN_PROB
|
||||||
|
(
|
||||||
|
DFORECAST_DATE in date, -- Дата прогноза
|
||||||
|
NFORECAST_DAYS in number, -- RUL-прогноз (дней до перехода в предельное состояние от даты прогноза)
|
||||||
|
DDATE in date -- Дата на
|
||||||
|
) return number; -- Значение вероятности
|
||||||
|
|
||||||
end UDO_PKG_EQUIPDS_BASE;
|
end UDO_PKG_EQUIPDS_BASE;
|
||||||
/
|
/
|
||||||
create or replace package body UDO_PKG_EQUIPDS_BASE as
|
create or replace package body UDO_PKG_EQUIPDS_BASE as
|
||||||
@ -390,6 +425,74 @@ create or replace package body UDO_PKG_EQUIPDS_BASE as
|
|||||||
return '№' || TO_CHAR(NDATASET_ID) || ' от ' || TO_CHAR(DDATASET_TS, 'dd.mm.yyyy hh24:mi:ss');
|
return '№' || TO_CHAR(NDATASET_ID) || ' от ' || TO_CHAR(DDATASET_TS, 'dd.mm.yyyy hh24:mi:ss');
|
||||||
end UTL_DATASET_MAKE_NAME;
|
end UTL_DATASET_MAKE_NAME;
|
||||||
|
|
||||||
|
/* Сериализация описания параметров выборки для прогноза */
|
||||||
|
procedure UTL_FORECAST_RQ_MAKE_CFG
|
||||||
|
(
|
||||||
|
DBEG in date, -- Дата "С"
|
||||||
|
DEND in date, -- Дата "По"
|
||||||
|
NINTERVAL in number, -- Длина интервала (в днях, если меньше дня, то дробное - 1/24 для часа, например)
|
||||||
|
CRQ_CFG out clob -- Сериализованное описание параметров выборки для прогноза
|
||||||
|
)
|
||||||
|
is
|
||||||
|
XDOC integer; -- Курсор для XML
|
||||||
|
XRESULT PKG_XMAKE.TNODE; -- XML-документ
|
||||||
|
begin
|
||||||
|
/* Проверим параметры */
|
||||||
|
if (DBEG is null) then
|
||||||
|
P_EXCEPTION(0, 'Не указана дата начала выборки для прогноза.');
|
||||||
|
end if;
|
||||||
|
if (DEND is null) then
|
||||||
|
P_EXCEPTION(0, 'Не указана дата окончания выборки для прогноза.');
|
||||||
|
end if;
|
||||||
|
if ((NINTERVAL is null) or (NINTERVAL <= 0)) then
|
||||||
|
P_EXCEPTION(0,
|
||||||
|
'Не указана или указана неверно длина интервала измерений выборки для прогноза.');
|
||||||
|
end if;
|
||||||
|
/* Создаём документ */
|
||||||
|
XDOC := PKG_XMAKE.OPEN_CURSOR();
|
||||||
|
/* Формируем документ */
|
||||||
|
XRESULT := PKG_XMAKE.ELEMENT(ICURSOR => XDOC,
|
||||||
|
SNAME => 'XDATA',
|
||||||
|
RNODE00 => PKG_XMAKE.ELEMENT(ICURSOR => XDOC,
|
||||||
|
SNAME => 'DBEG',
|
||||||
|
RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => XDOC, DVALUE => DBEG)),
|
||||||
|
RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => XDOC,
|
||||||
|
SNAME => 'DEND',
|
||||||
|
RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => XDOC, DVALUE => DEND)),
|
||||||
|
RNODE02 => PKG_XMAKE.ELEMENT(ICURSOR => XDOC,
|
||||||
|
SNAME => 'NINTERVAL',
|
||||||
|
RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => XDOC,
|
||||||
|
NVALUE => NINTERVAL)));
|
||||||
|
/* Сериализуем */
|
||||||
|
CRQ_CFG := PKG_XMAKE.SERIALIZE_TO_CLOB(ICURSOR => XDOC, ITYPE => PKG_XMAKE.CONTENT_, RNODE => XRESULT);
|
||||||
|
/* Освобождаем документ */
|
||||||
|
PKG_XMAKE.CLOSE_CURSOR(ICURSOR => XDOC);
|
||||||
|
end UTL_FORECAST_RQ_MAKE_CFG;
|
||||||
|
|
||||||
|
/* Десериализация описания параметров выборки для прогноза */
|
||||||
|
procedure UTL_FORECAST_RQ_PARSE_CFG
|
||||||
|
(
|
||||||
|
CRQ_CFG in clob, -- Сериализованное описание параметров выборки для прогноза
|
||||||
|
DBEG out date, -- Дата "С"
|
||||||
|
DEND out date, -- Дата "По"
|
||||||
|
NINTERVAL out number -- Длина интервала (в днях, если меньше дня, то дробное - 1/24 для часа, например)
|
||||||
|
)
|
||||||
|
is
|
||||||
|
XDOC PKG_XPATH.TDOCUMENT; -- XML-документ
|
||||||
|
XROOT PKG_XPATH.TNODE; -- Корневой элемент
|
||||||
|
begin
|
||||||
|
/* Разбираем документ */
|
||||||
|
XDOC := PKG_XPATH.PARSE_FROM_CLOB(LCXML => CRQ_CFG);
|
||||||
|
/* Находим корень */
|
||||||
|
XROOT := PKG_XPATH.ROOT_NODE(RDOCUMENT => XDOC);
|
||||||
|
/* Читаем параметры */
|
||||||
|
DBEG := PKG_XPATH.VALUE_DATE(RNODE => XROOT, SPATTERN => 'XDATA/DBEG');
|
||||||
|
DEND := PKG_XPATH.VALUE_DATE(RNODE => XROOT, SPATTERN => 'XDATA/DEND');
|
||||||
|
NINTERVAL := PKG_XPATH.VALUE_NUM(RNODE => XROOT, SPATTERN => 'XDATA/NINTERVAL');
|
||||||
|
/* Освобождаем документ */
|
||||||
|
PKG_XPATH.FREE(RDOCUMENT => XDOC);
|
||||||
|
end UTL_FORECAST_RQ_PARSE_CFG;
|
||||||
|
|
||||||
/* Считывание записи "Выборки данных оборудования" по регистрационному номеру */
|
/* Считывание записи "Выборки данных оборудования" по регистрационному номеру */
|
||||||
function GET
|
function GET
|
||||||
(
|
(
|
||||||
@ -1235,40 +1338,25 @@ create or replace package body UDO_PKG_EQUIPDS_BASE as
|
|||||||
'идентификаторы файлового буфера с подготовленными данными (CSV), описанием структуры данных (XML) и описанием параметров запроса (XML) для интерпретации прогноза соответственно.';
|
'идентификаторы файлового буфера с подготовленными данными (CSV), описанием структуры данных (XML) и описанием параметров запроса (XML) для интерпретации прогноза соответственно.';
|
||||||
end CMML_USERPROCS_FRCST_DATA_HINT;
|
end CMML_USERPROCS_FRCST_DATA_HINT;
|
||||||
|
|
||||||
/* Вычисление вероятности выхода из строя на дату по RUL-прогнозу */
|
/* Считывание записи "Выборки данных оборудования (классы оборудования, модели, история запросов)" по регистрационному номеру */
|
||||||
function CMML_RUL_BREAKDOWN_PROB
|
function CMMLH_GET
|
||||||
(
|
(
|
||||||
NFORECAST in number, -- RUL-прогноз (интервалов до перехода в предельное состояние)
|
NFLAG_SMART in number, -- Признак выдачи сообщения об ошибке (0 - выдавать, 1 - не выдавать)
|
||||||
DFORECAST_DATE in date, -- Дата прогноза
|
NRN in number -- Регистрационный номер
|
||||||
DDATE in date -- Дата на
|
) return UDO_T_EQUIPDSCMMLH%rowtype -- Запись итории прогонозов модели
|
||||||
) return number -- Значение вероятности
|
|
||||||
is
|
is
|
||||||
NRES PKG_STD.TNUMBER; -- Буфер для результата
|
RES UDO_T_EQUIPDSCMMLH%rowtype; -- Буфер для результата
|
||||||
begin
|
begin
|
||||||
/* Проверим параметры */
|
/* Считывание записи */
|
||||||
if ((NFORECAST is null) or (DFORECAST_DATE is null) or (DDATE is null) or (DDATE < DFORECAST_DATE) or
|
begin
|
||||||
(DFORECAST_DATE > sysdate) or (DDATE < sysdate)) then
|
select T.* into RES from UDO_T_EQUIPDSCMMLH T where T.RN = NRN;
|
||||||
return null;
|
exception
|
||||||
end if;
|
when NO_DATA_FOUND then
|
||||||
/* Проверяем пограничные значения */
|
PKG_MSG.RECORD_NOT_FOUND(NFLAG_SMART => NFLAG_SMART, NDOCUMENT => NRN, SUNIT_TABLE => 'UDO_T_EQUIPDSCMMLH');
|
||||||
if (NFORECAST = 0) or ((DDATE - sysdate) = 0) then
|
end;
|
||||||
return 100;
|
/* Возврат результата */
|
||||||
end if;
|
return RES;
|
||||||
if (sysdate + NFORECAST > DDATE) then
|
end CMMLH_GET;
|
||||||
return 0;
|
|
||||||
end if;
|
|
||||||
/* Вычисляем */
|
|
||||||
NRES := 100 - ROUND((NFORECAST - (TRUNC(sysdate) - TRUNC(DFORECAST_DATE))) / (DDATE - sysdate) * 100);
|
|
||||||
/* Корректируем флуктуации */
|
|
||||||
if (NRES > 100) then
|
|
||||||
NRES := 100;
|
|
||||||
end if;
|
|
||||||
if (NRES < 0) then
|
|
||||||
NRES := 0;
|
|
||||||
end if;
|
|
||||||
/* Возвращаем результат */
|
|
||||||
return NRES;
|
|
||||||
end CMML_RUL_BREAKDOWN_PROB;
|
|
||||||
|
|
||||||
/* Базовое добавление "Выборки данных оборудования (классы оборудования, модели, история запросов)" */
|
/* Базовое добавление "Выборки данных оборудования (классы оборудования, модели, история запросов)" */
|
||||||
procedure CMMLH_INS
|
procedure CMMLH_INS
|
||||||
@ -1286,9 +1374,9 @@ create or replace package body UDO_PKG_EQUIPDS_BASE as
|
|||||||
NRN := GEN_ID();
|
NRN := GEN_ID();
|
||||||
/* Добавляем запись */
|
/* Добавляем запись */
|
||||||
insert into UDO_T_EQUIPDSCMMLH
|
insert into UDO_T_EQUIPDSCMMLH
|
||||||
(RN, PRN, EQCONFIG, RQ_AUTHID, RQ_DATE, RQ, FORECAST)
|
(RN, PRN, EQCONFIG, RQ_AUTHID, RQ_DATE, RQ, FORECAST, FORECAST_DATE, FORECAST_DAYS)
|
||||||
values
|
values
|
||||||
(NRN, NPRN, NEQCONFIG, SRQ_AUTHID, DRQ_DATE, BRQ, null);
|
(NRN, NPRN, NEQCONFIG, SRQ_AUTHID, DRQ_DATE, BRQ, null, null, null);
|
||||||
end CMMLH_INS;
|
end CMMLH_INS;
|
||||||
|
|
||||||
/* Базовое удаление "Выборки данных оборудования (классы оборудования, модели, история запросов)" */
|
/* Базовое удаление "Выборки данных оборудования (классы оборудования, модели, история запросов)" */
|
||||||
@ -1306,13 +1394,71 @@ create or replace package body UDO_PKG_EQUIPDS_BASE as
|
|||||||
procedure CMMLH_SET_FORECAST
|
procedure CMMLH_SET_FORECAST
|
||||||
(
|
(
|
||||||
NRN in number, -- Регистрационный номер
|
NRN in number, -- Регистрационный номер
|
||||||
BFORECAST in blob -- Данные прогноза
|
BFORECAST in blob, -- Данные прогноза
|
||||||
|
DFORECAST_DATE in date, -- Дата прогноза
|
||||||
|
NFORECAST_DAYS in number -- Прогноз (дней до выхода из строя на дату прогноза)
|
||||||
)
|
)
|
||||||
is
|
is
|
||||||
begin
|
begin
|
||||||
/* Установим данные ответа */
|
/* Установим данные прогноза */
|
||||||
update UDO_T_EQUIPDSCMMLH T set T.FORECAST = BFORECAST where T.RN = NRN;
|
update UDO_T_EQUIPDSCMMLH T
|
||||||
|
set T.FORECAST = BFORECAST,
|
||||||
|
T.FORECAST_DATE = DFORECAST_DATE,
|
||||||
|
T.FORECAST_DAYS = NFORECAST_DAYS
|
||||||
|
where T.RN = NRN;
|
||||||
end CMMLH_SET_FORECAST;
|
end CMMLH_SET_FORECAST;
|
||||||
|
|
||||||
|
/* Вычисление количества дней до выхода из строя от даты */
|
||||||
|
function CMMLH_FORECAST_DAYS_NOW
|
||||||
|
(
|
||||||
|
DFORECAST_DATE in date, -- Дата прогноза
|
||||||
|
NFORECAST_DAYS in number, -- RUL-прогноз (дней до перехода в предельное состояние от даты прогноза)
|
||||||
|
DDATE in date := sysdate -- Дата (не задана - текущая)
|
||||||
|
) return number -- Количество дней до выхода из строя
|
||||||
|
is
|
||||||
|
NRES PKG_STD.TNUMBER; -- Буфер для результата
|
||||||
|
begin
|
||||||
|
/* От прогнозной даты выхода из строя (дата прогноза + дней до перехода в предельное состояние от неё) отнимем текущую дату */
|
||||||
|
NRES := ROUND((DFORECAST_DATE + NFORECAST_DAYS) - COALESCE(DDATE, sysdate));
|
||||||
|
/* Если дело прошлое - скажем, что осталось 0 дней */
|
||||||
|
if (NRES < 0) then
|
||||||
|
NRES := 0;
|
||||||
|
end if;
|
||||||
|
/* Вренём результат */
|
||||||
|
return NRES;
|
||||||
|
end CMMLH_FORECAST_DAYS_NOW;
|
||||||
|
|
||||||
|
/* Вычисление вероятности выхода из строя на дату по RUL-прогнозу */
|
||||||
|
function CMMLH_RUL_BREAKDOWN_PROB
|
||||||
|
(
|
||||||
|
DFORECAST_DATE in date, -- Дата прогноза
|
||||||
|
NFORECAST_DAYS in number, -- RUL-прогноз (дней до перехода в предельное состояние от даты прогноза)
|
||||||
|
DDATE in date -- Дата на
|
||||||
|
) return number -- Значение вероятности
|
||||||
|
is
|
||||||
|
NRES PKG_STD.TNUMBER; -- Буфер для результата
|
||||||
|
begin
|
||||||
|
/* Проверим параметры */
|
||||||
|
if ((NFORECAST_DAYS is null) or (DFORECAST_DATE is null) or (DDATE is null) or (DDATE < DFORECAST_DATE) or
|
||||||
|
(DFORECAST_DATE > sysdate) or (DDATE < sysdate)) then
|
||||||
|
return null;
|
||||||
|
end if;
|
||||||
|
/* Проверяем пограничные значения */
|
||||||
|
if ((NFORECAST_DAYS = 0) or ((DDATE - sysdate) = 0)) then
|
||||||
|
return 100;
|
||||||
|
end if;
|
||||||
|
/* Вычисляем */
|
||||||
|
NRES := 100 - ROUND((NFORECAST_DAYS - (TRUNC(sysdate) - TRUNC(DFORECAST_DATE))) / (DDATE - sysdate) * 100);
|
||||||
|
/* Корректируем флуктуации */
|
||||||
|
if (NRES > 100) then
|
||||||
|
NRES := 100;
|
||||||
|
end if;
|
||||||
|
if (NRES < 0) then
|
||||||
|
NRES := 0;
|
||||||
|
end if;
|
||||||
|
/* Возвращаем результат */
|
||||||
|
return NRES;
|
||||||
|
end CMMLH_RUL_BREAKDOWN_PROB;
|
||||||
|
|
||||||
end UDO_PKG_EQUIPDS_BASE;
|
end UDO_PKG_EQUIPDS_BASE;
|
||||||
/
|
/
|
||||||
|
@ -592,6 +592,8 @@ is
|
|||||||
SERR_NTF_MAIL => null,
|
SERR_NTF_MAIL => null,
|
||||||
NAUTH_ONLY => PKG_EXS.NAUTH_ONLY_NO,
|
NAUTH_ONLY => PKG_EXS.NAUTH_ONLY_NO,
|
||||||
NSAVE_QUEUE => PKG_EXS.NFN_SAVE_QUEUE,
|
NSAVE_QUEUE => PKG_EXS.NFN_SAVE_QUEUE,
|
||||||
|
NTIMEOUT_CONN => null,
|
||||||
|
NTIMEOUT_ASYNCH => null,
|
||||||
NFORCE_UPDATE => NFORCE_UPDATE,
|
NFORCE_UPDATE => NFORCE_UPDATE,
|
||||||
NRN => NEXSSERVICEFN);
|
NRN => NEXSSERVICEFN);
|
||||||
|
|
||||||
@ -623,6 +625,8 @@ is
|
|||||||
SERR_NTF_MAIL => null,
|
SERR_NTF_MAIL => null,
|
||||||
NAUTH_ONLY => PKG_EXS.NAUTH_ONLY_NO,
|
NAUTH_ONLY => PKG_EXS.NAUTH_ONLY_NO,
|
||||||
NSAVE_QUEUE => PKG_EXS.NFN_SAVE_QUEUE,
|
NSAVE_QUEUE => PKG_EXS.NFN_SAVE_QUEUE,
|
||||||
|
NTIMEOUT_CONN => null,
|
||||||
|
NTIMEOUT_ASYNCH => null,
|
||||||
NFORCE_UPDATE => NFORCE_UPDATE,
|
NFORCE_UPDATE => NFORCE_UPDATE,
|
||||||
NRN => NEXSSERVICEFN);
|
NRN => NEXSSERVICEFN);
|
||||||
/* Загрузка функции сервиса обмена */
|
/* Загрузка функции сервиса обмена */
|
||||||
@ -640,6 +644,8 @@ is
|
|||||||
SERR_NTF_MAIL => null,
|
SERR_NTF_MAIL => null,
|
||||||
NAUTH_ONLY => PKG_EXS.NAUTH_ONLY_NO,
|
NAUTH_ONLY => PKG_EXS.NAUTH_ONLY_NO,
|
||||||
NSAVE_QUEUE => PKG_EXS.NFN_SAVE_QUEUE,
|
NSAVE_QUEUE => PKG_EXS.NFN_SAVE_QUEUE,
|
||||||
|
NTIMEOUT_CONN => null,
|
||||||
|
NTIMEOUT_ASYNCH => null,
|
||||||
NFORCE_UPDATE => NFORCE_UPDATE,
|
NFORCE_UPDATE => NFORCE_UPDATE,
|
||||||
NRN => NEXSSERVICEFN);
|
NRN => NEXSSERVICEFN);
|
||||||
|
|
||||||
@ -671,6 +677,8 @@ is
|
|||||||
SERR_NTF_MAIL => null,
|
SERR_NTF_MAIL => null,
|
||||||
NAUTH_ONLY => PKG_EXS.NAUTH_ONLY_NO,
|
NAUTH_ONLY => PKG_EXS.NAUTH_ONLY_NO,
|
||||||
NSAVE_QUEUE => PKG_EXS.NFN_SAVE_QUEUE,
|
NSAVE_QUEUE => PKG_EXS.NFN_SAVE_QUEUE,
|
||||||
|
NTIMEOUT_CONN => null,
|
||||||
|
NTIMEOUT_ASYNCH => null,
|
||||||
NFORCE_UPDATE => NFORCE_UPDATE,
|
NFORCE_UPDATE => NFORCE_UPDATE,
|
||||||
NRN => NEXSSERVICEFN);
|
NRN => NEXSSERVICEFN);
|
||||||
/* Загрузка функции сервиса обмена */
|
/* Загрузка функции сервиса обмена */
|
||||||
@ -688,6 +696,8 @@ is
|
|||||||
SERR_NTF_MAIL => null,
|
SERR_NTF_MAIL => null,
|
||||||
NAUTH_ONLY => PKG_EXS.NAUTH_ONLY_NO,
|
NAUTH_ONLY => PKG_EXS.NAUTH_ONLY_NO,
|
||||||
NSAVE_QUEUE => PKG_EXS.NFN_SAVE_QUEUE,
|
NSAVE_QUEUE => PKG_EXS.NFN_SAVE_QUEUE,
|
||||||
|
NTIMEOUT_CONN => null,
|
||||||
|
NTIMEOUT_ASYNCH => null,
|
||||||
NFORCE_UPDATE => NFORCE_UPDATE,
|
NFORCE_UPDATE => NFORCE_UPDATE,
|
||||||
NRN => NEXSSERVICEFN);
|
NRN => NEXSSERVICEFN);
|
||||||
|
|
||||||
|
@ -54,6 +54,12 @@ create or replace package UDO_PKG_EQUIPTCF as
|
|||||||
NIDENT out number -- Идентификатор списка
|
NIDENT out number -- Идентификатор списка
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/* Получение даты следующего ремонта по ремонтной ведомости или графику ТО и ремонтов (что раньше) технического объекта */
|
||||||
|
function EQCONFIG_THOBJ_GEN_NXTRPR
|
||||||
|
(
|
||||||
|
NEQCONFIG in number -- Рег. номер технического объекта
|
||||||
|
) return date; -- Дата ближайшего ремонта
|
||||||
|
|
||||||
/* Формирование карточки технического объекта */
|
/* Формирование карточки технического объекта */
|
||||||
procedure EQCONFIG_THOBJ_CARD
|
procedure EQCONFIG_THOBJ_CARD
|
||||||
(
|
(
|
||||||
@ -96,32 +102,6 @@ create or replace package UDO_PKG_EQUIPTCF as
|
|||||||
CFORECAST in clob := 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-прогноза */
|
/* Вероятность выхода единицы оборудования из строя с учётом графика ТО и ремонтов и RUL-прогноза */
|
||||||
function EQCONFIG_THOBJ_TCHSRV_BRKDPROB
|
function EQCONFIG_THOBJ_TCHSRV_BRKDPROB
|
||||||
(
|
(
|
||||||
@ -413,7 +393,7 @@ text="Проверка прав доступа при формировании
|
|||||||
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
|
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
|
||||||
BORDER => true,
|
BORDER => true,
|
||||||
BFILTER => true,
|
BFILTER => true,
|
||||||
SHINT => EQCONFIG_THOBJ_FORECAST_CLR(NMODE => 0));
|
SHINT => UDO_PKG_EQUIPDS.CMMLH_FORECAST_COLOR(NMODE => 0));
|
||||||
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
|
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
|
||||||
SNAME => 'SBREAKDOWN_PROB_COLOR',
|
SNAME => 'SBREAKDOWN_PROB_COLOR',
|
||||||
SCAPTION => 'Цвет вероятности выхода из строя',
|
SCAPTION => 'Цвет вероятности выхода из строя',
|
||||||
@ -526,7 +506,7 @@ text="Проверка прав доступа при формировании
|
|||||||
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 => 'NBREAKDOWN_PROB', NVALUE => NBREAKDOWN_PROB);
|
||||||
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW,
|
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW,
|
||||||
SNAME => 'SBREAKDOWN_PROB_COLOR',
|
SNAME => 'SBREAKDOWN_PROB_COLOR',
|
||||||
SVALUE => EQCONFIG_THOBJ_FORECAST_CLR(NMODE => 1, NVALUE => NBREAKDOWN_PROB));
|
SVALUE => UDO_PKG_EQUIPDS.CMMLH_FORECAST_COLOR(NMODE => 1, NVALUE => NBREAKDOWN_PROB));
|
||||||
/* Добавляем строку в таблицу */
|
/* Добавляем строку в таблицу */
|
||||||
PKG_P8PANELS_VISUAL.TDG_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
|
PKG_P8PANELS_VISUAL.TDG_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
|
||||||
end loop;
|
end loop;
|
||||||
@ -850,7 +830,7 @@ text="Проверка прав доступа при формировании
|
|||||||
into NCNT
|
into NCNT
|
||||||
from FILE_BUFFER T
|
from FILE_BUFFER T
|
||||||
where T.IDENT = NREQUEST_CONFIG_IDENT
|
where T.IDENT = NREQUEST_CONFIG_IDENT
|
||||||
and T.BDATA is not null;
|
and T.DATA is not null;
|
||||||
exception
|
exception
|
||||||
when others then
|
when others then
|
||||||
P_EXCEPTION(0,
|
P_EXCEPTION(0,
|
||||||
@ -933,30 +913,73 @@ text="Проверка прав доступа при формировании
|
|||||||
)
|
)
|
||||||
is
|
is
|
||||||
NEQUIPDSCMMLH PKG_STD.TREF; -- Рег. номер истории запросов модели
|
NEQUIPDSCMMLH PKG_STD.TREF; -- Рег. номер истории запросов модели
|
||||||
BRQ blob; -- Описание параметров запроса на прогноз
|
CRQ clob; -- Описание параметров запроса на прогноз
|
||||||
|
DFORECAST_DATE PKG_STD.TLDATE; -- Дата прогноза (последняя)
|
||||||
|
NFORECAST_DAYS PKG_STD.TNUMBER; -- Прогноз (дней до выхода из строя на дату прогноза)
|
||||||
|
DBEG PKG_STD.TLDATE; -- Дата окончания интервала сбора данных для прогноза
|
||||||
|
DEND PKG_STD.TLDATE; -- Дата начала интервала сбора данных для прогноза
|
||||||
|
NINTERVAL PKG_STD.TLNUMBER; -- Размер (в днях) интервала измерения
|
||||||
|
XFORECAST PKG_XPATH.TDOCUMENT; -- XML-документ прогноза
|
||||||
|
XROOT PKG_XPATH.TNODE; -- Корневой элемент документа прогноза
|
||||||
|
XFCTS PKG_XPATH.TNODES; -- Массив предсказаний
|
||||||
|
XLAST_FCT PKG_XPATH.TNODE; -- Последний элемент массива предсказаний
|
||||||
|
NLAST PKG_STD.TNUMBER; -- Номер последней позиции массива предсказаний
|
||||||
|
NLAST_INTERVALS PKG_STD.TLNUMBER; -- Значение (количество интервалов измерения до выхода из строя) последней записи массива предсказаний
|
||||||
begin
|
begin
|
||||||
/* Считаем параметры сделанного запроса */
|
/* Считаем параметры сделанного запроса */
|
||||||
begin
|
begin
|
||||||
select T.BDATA
|
select T.DATA
|
||||||
into BRQ
|
into CRQ
|
||||||
from FILE_BUFFER T
|
from FILE_BUFFER T
|
||||||
where T.IDENT = NREQUEST_CONFIG_IDENT
|
where T.IDENT = NREQUEST_CONFIG_IDENT
|
||||||
and T.BDATA is not null;
|
and T.DATA is not null;
|
||||||
exception
|
exception
|
||||||
when NO_DATA_FOUND then
|
when NO_DATA_FOUND then
|
||||||
P_EXCEPTION(0, 'Параметры запроса на прогнозирование не определёны.');
|
P_EXCEPTION(0,
|
||||||
|
'Параметры запроса на прогнозирование не определёны.');
|
||||||
when TOO_MANY_ROWS then
|
when TOO_MANY_ROWS then
|
||||||
P_EXCEPTION(0, 'Параметры запроса на прогнозирование определёны неоднозначно.');
|
P_EXCEPTION(0,
|
||||||
|
'Параметры запроса на прогнозирование определёны неоднозначно.');
|
||||||
end;
|
end;
|
||||||
/* Добавляем запись истории запросов */
|
/* Добавляем запись истории запросов */
|
||||||
UDO_PKG_EQUIPDS_BASE.CMMLH_INS(NPRN => NEQUIPDSCMML,
|
UDO_PKG_EQUIPDS_BASE.CMMLH_INS(NPRN => NEQUIPDSCMML,
|
||||||
NEQCONFIG => NEQCONFIG,
|
NEQCONFIG => NEQCONFIG,
|
||||||
SRQ_AUTHID => UTILIZER(),
|
SRQ_AUTHID => UTILIZER(),
|
||||||
DRQ_DATE => sysdate,
|
DRQ_DATE => sysdate,
|
||||||
BRQ => BRQ,
|
BRQ => CLOB2BLOB(LCDATA => CRQ),
|
||||||
NRN => NEQUIPDSCMMLH);
|
NRN => NEQUIPDSCMMLH);
|
||||||
|
/* Пробуем разобрать прогноз */
|
||||||
|
begin
|
||||||
|
/* Читаем параметры с которыми делался прогноз */
|
||||||
|
UDO_PKG_EQUIPDS_BASE.UTL_FORECAST_RQ_PARSE_CFG(CRQ_CFG => CRQ,
|
||||||
|
DBEG => DBEG,
|
||||||
|
DEND => DEND,
|
||||||
|
NINTERVAL => NINTERVAL);
|
||||||
|
/* Разбираем данные прогноза */
|
||||||
|
XFORECAST := PKG_XPATH.PARSE_FROM_BLOB(LBXML => BASE64_DECODE(LCSRCE => CFORECAST));
|
||||||
|
XROOT := PKG_XPATH.ROOT_NODE(RDOCUMENT => XFORECAST);
|
||||||
|
XFCTS := PKG_XPATH.LIST_NODES(RPARENT_NODE => XROOT, SPATTERN => 'XDATA/XFORECAST');
|
||||||
|
/* Читаем последнее значение из массива предсказаний (оно соответствует дате окончания из параметров прогноза) */
|
||||||
|
NLAST := PKG_XPATH.COUNT_NODES(RNODES => XFCTS);
|
||||||
|
XLAST_FCT := PKG_XPATH.ITEM_NODE(RNODES => XFCTS, INUMBER => NLAST);
|
||||||
|
NLAST_INTERVALS := TO_CHAR(PKG_XPATH.VALUE(RNODE => XLAST_FCT, SPATTERN => 'SVALUE'));
|
||||||
|
if (NLAST_INTERVALS < 0) then
|
||||||
|
NLAST_INTERVALS := 0;
|
||||||
|
end if;
|
||||||
|
/* Освобождаем документ */
|
||||||
|
PKG_XPATH.FREE(RDOCUMENT => XFORECAST);
|
||||||
|
/* Сформируем дату прогноза и количество дней до выхода из строя на эту дату */
|
||||||
|
DFORECAST_DATE := DEND;
|
||||||
|
NFORECAST_DAYS := NINTERVAL * NLAST_INTERVALS;
|
||||||
|
exception
|
||||||
|
when others then
|
||||||
|
null;
|
||||||
|
end;
|
||||||
/* Сохраним данные прогноза */
|
/* Сохраним данные прогноза */
|
||||||
UDO_PKG_EQUIPDS_BASE.CMMLH_SET_FORECAST(NRN => NEQUIPDSCMMLH, BFORECAST => BASE64_DECODE(LCSRCE => CFORECAST));
|
UDO_PKG_EQUIPDS_BASE.CMMLH_SET_FORECAST(NRN => NEQUIPDSCMMLH,
|
||||||
|
BFORECAST => BASE64_DECODE(LCSRCE => CFORECAST),
|
||||||
|
DFORECAST_DATE => DFORECAST_DATE,
|
||||||
|
NFORECAST_DAYS => NFORECAST_DAYS);
|
||||||
/* Подчистим буферы */
|
/* Подчистим буферы */
|
||||||
EQCONFIG_THOBJ_FORECAST_BCLR(NDATASET_IDENT => NDATASET_IDENT,
|
EQCONFIG_THOBJ_FORECAST_BCLR(NDATASET_IDENT => NDATASET_IDENT,
|
||||||
NDATASET_CONFIG_IDENT => NDATASET_CONFIG_IDENT,
|
NDATASET_CONFIG_IDENT => NDATASET_CONFIG_IDENT,
|
||||||
@ -971,228 +994,6 @@ text="Проверка прав доступа при формировании
|
|||||||
raise;
|
raise;
|
||||||
end EQCONFIG_THOBJ_FORECAST_EPLG;
|
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-прогноза */
|
/* Вероятность выхода единицы оборудования из строя с учётом графика ТО и ремонтов и RUL-прогноза */
|
||||||
function EQCONFIG_THOBJ_TCHSRV_BRKDPROB
|
function EQCONFIG_THOBJ_TCHSRV_BRKDPROB
|
||||||
(
|
(
|
||||||
@ -1201,7 +1002,7 @@ text="Проверка прав доступа при формировании
|
|||||||
is
|
is
|
||||||
NRES PKG_STD.TNUMBER; -- Буфер для результата
|
NRES PKG_STD.TNUMBER; -- Буфер для результата
|
||||||
DFORECAST_DATE PKG_STD.TLDATE; -- Дата прогноза
|
DFORECAST_DATE PKG_STD.TLDATE; -- Дата прогноза
|
||||||
NFORECAST PKG_STD.TNUMBER; -- Значение самго свежего прогноза модели
|
NFORECAST_DAYS PKG_STD.TNUMBER; -- Значение самго свежего прогноза модели
|
||||||
DCALC_DATE PKG_STD.TLDATE; -- Дата расчета вероятности
|
DCALC_DATE PKG_STD.TLDATE; -- Дата расчета вероятности
|
||||||
begin
|
begin
|
||||||
/* Определим дату ближайшего ТО или ремонта */
|
/* Определим дату ближайшего ТО или ремонта */
|
||||||
@ -1209,8 +1010,8 @@ text="Проверка прав доступа при формировании
|
|||||||
/* Если дата есть */
|
/* Если дата есть */
|
||||||
if (DCALC_DATE is not null) then
|
if (DCALC_DATE is not null) then
|
||||||
/* Вынем самый свежий прогноз */
|
/* Вынем самый свежий прогноз */
|
||||||
for C in (select T.RQ_DATE DFORECAST_DATE,
|
for C in (select T.FORECAST_DATE DFORECAST_DATE,
|
||||||
T.FORECAST
|
T.FORECAST_DAYS NFORECAST_DAYS
|
||||||
from UDO_T_EQUIPDSCMMLH T,
|
from UDO_T_EQUIPDSCMMLH T,
|
||||||
UDO_T_EQUIPDSCMML CMML
|
UDO_T_EQUIPDSCMML CMML
|
||||||
where T.EQCONFIG = NEQCONFIG
|
where T.EQCONFIG = NEQCONFIG
|
||||||
@ -1219,13 +1020,13 @@ text="Проверка прав доступа при формировании
|
|||||||
order by T.RQ_DATE desc)
|
order by T.RQ_DATE desc)
|
||||||
loop
|
loop
|
||||||
DFORECAST_DATE := C.DFORECAST_DATE;
|
DFORECAST_DATE := C.DFORECAST_DATE;
|
||||||
UDO_PKG_EQUIPDS.CMMLH_PARSE_FORECAST(CFORECAST => BLOB2CLOB(LBDATA => C.FORECAST), NFORECAST => NFORECAST);
|
NFORECAST_DAYS := C.NFORECAST_DAYS;
|
||||||
exit;
|
exit;
|
||||||
end loop;
|
end loop;
|
||||||
/* Если есть и прогноз */
|
/* Если есть и прогноз */
|
||||||
if (NFORECAST is not null) then
|
if (NFORECAST_DAYS is not null) then
|
||||||
NRES := UDO_PKG_EQUIPDS_BASE.CMML_RUL_BREAKDOWN_PROB(NFORECAST => NFORECAST,
|
NRES := UDO_PKG_EQUIPDS_BASE.CMMLH_RUL_BREAKDOWN_PROB(DFORECAST_DATE => DFORECAST_DATE,
|
||||||
DFORECAST_DATE => DFORECAST_DATE,
|
NFORECAST_DAYS => NFORECAST_DAYS,
|
||||||
DDATE => DCALC_DATE);
|
DDATE => DCALC_DATE);
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
@ -1325,7 +1126,6 @@ text="Проверка прав доступа при формировании
|
|||||||
SEQTECSRVKIND in varchar2, -- Вид ремонта
|
SEQTECSRVKIND in varchar2, -- Вид ремонта
|
||||||
DPLANDATE_FROM in date, -- Плановая дата начала ремонта
|
DPLANDATE_FROM in date, -- Плановая дата начала ремонта
|
||||||
NIDENT out number -- Идентификатор списка сформированных ведомостей
|
NIDENT out number -- Идентификатор списка сформированных ведомостей
|
||||||
|
|
||||||
)
|
)
|
||||||
is
|
is
|
||||||
NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Рег. номер организации
|
NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Рег. номер организации
|
||||||
@ -1372,8 +1172,8 @@ text="Проверка прав доступа при формировании
|
|||||||
SNUMB => SNUMB,
|
SNUMB => SNUMB,
|
||||||
DDOCDATE => sysdate,
|
DDOCDATE => sysdate,
|
||||||
SJURPERSONS => SJURPERSONS,
|
SJURPERSONS => SJURPERSONS,
|
||||||
DPLANDATE_FROM => DPLANDATE_FROM,
|
DPLANDATE_FROM => TRUNC(DPLANDATE_FROM),
|
||||||
DPLANDATE_TO => DPLANDATE_FROM,
|
DPLANDATE_TO => (TRUNC(DPLANDATE_FROM) + 1) - 1/24/60,
|
||||||
SCURRENCY => SCURRENCY,
|
SCURRENCY => SCURRENCY,
|
||||||
NCOURSE => 1,
|
NCOURSE => 1,
|
||||||
SEQTECSRVKIND => SEQTECSRVKIND,
|
SEQTECSRVKIND => SEQTECSRVKIND,
|
||||||
|
@ -9,6 +9,7 @@ create or replace procedure UDO_P_EQCONFIG_DATASET_MAKE
|
|||||||
NREQUEST_CONFIG_IDENT out number -- Идентификатор буфера описания запроса
|
NREQUEST_CONFIG_IDENT out number -- Идентификатор буфера описания запроса
|
||||||
)
|
)
|
||||||
is
|
is
|
||||||
|
CREQUEST_CONFIG clob; -- Буфер для описания запроса
|
||||||
begin
|
begin
|
||||||
/* НАЧАЛО: Временная заглушка с отладочными данными (удалить) */
|
/* НАЧАЛО: Временная заглушка с отладочными данными (удалить) */
|
||||||
/* create table UDO_T_FILE_BUFFER as select * from FILE_BUFFER; */
|
/* create table UDO_T_FILE_BUFFER as select * from FILE_BUFFER; */
|
||||||
@ -25,6 +26,13 @@ begin
|
|||||||
P_FILE_BUFFER_INSERT(NIDENT => NDATASET_IDENT, CFILENAME => C.FILENAME, CDATA => C.DATA, BLOBDATA => C.BDATA);
|
P_FILE_BUFFER_INSERT(NIDENT => NDATASET_IDENT, CFILENAME => C.FILENAME, CDATA => C.DATA, BLOBDATA => C.BDATA);
|
||||||
end if;
|
end if;
|
||||||
end loop;
|
end loop;
|
||||||
|
/* Сформируем описание параметров выборки (ПРИ УДАЛЕНИИ ЗАГЛУШКИ ЭТО НАДО ОСТАВИТЬ) */
|
||||||
|
NREQUEST_CONFIG_IDENT := GEN_IDENT();
|
||||||
|
UDO_PKG_EQUIPDS_BASE.UTL_FORECAST_RQ_MAKE_CFG(DBEG => DBEG, DEND => DEND, NINTERVAL => 1, CRQ_CFG => CREQUEST_CONFIG);
|
||||||
|
P_FILE_BUFFER_INSERT(NIDENT => NREQUEST_CONFIG_IDENT,
|
||||||
|
CFILENAME => TO_CHAR(NREQUEST_CONFIG_IDENT) || '.xml',
|
||||||
|
CDATA => CREQUEST_CONFIG,
|
||||||
|
BLOBDATA => null);
|
||||||
return;
|
return;
|
||||||
/* КОНЕЦ: Временная заглушка с отладочными данными (удалить) */
|
/* КОНЕЦ: Временная заглушка с отладочными данными (удалить) */
|
||||||
/* Обратимся к еденице оборудования */
|
/* Обратимся к еденице оборудования */
|
||||||
|
@ -15,6 +15,10 @@ create table UDO_T_EQUIPDSCMMLH
|
|||||||
RQ blob,
|
RQ blob,
|
||||||
/* Данные прогноза */
|
/* Данные прогноза */
|
||||||
FORECAST blob,
|
FORECAST blob,
|
||||||
|
/* Дата прогноза (последняя) */
|
||||||
|
FORECAST_DATE date default null,
|
||||||
|
/* Прогноз (дней до выхода из строя на дату прогноза) */
|
||||||
|
FORECAST_DAYS number(17) default null,
|
||||||
/* Ключи */
|
/* Ключи */
|
||||||
constraint UDO_C_EQUIPDSCMMLH_RN_PK primary key (RN),
|
constraint UDO_C_EQUIPDSCMMLH_RN_PK primary key (RN),
|
||||||
constraint UDO_C_EQUIPDSCMMLH_PRN_FK foreign key (PRN) references UDO_T_EQUIPDSCMML(RN),
|
constraint UDO_C_EQUIPDSCMMLH_PRN_FK foreign key (PRN) references UDO_T_EQUIPDSCMML(RN),
|
||||||
|
@ -241,7 +241,7 @@ const ForecastTab = ({ onGoToAdmin }) => {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw new Error("Неожиданный ответ системы прогнозирования: ответ неверного формата.");
|
throw new Error("Неожиданный ответ системы прогнозирования: ответ неверного формата.");
|
||||||
}
|
}
|
||||||
if (response) {
|
if (responseJson) {
|
||||||
if (responseJson?.status && responseJson.status == "ERR")
|
if (responseJson?.status && responseJson.status == "ERR")
|
||||||
throw new Error(`Ошибка формирования прогноза: ${responseJson.message}`);
|
throw new Error(`Ошибка формирования прогноза: ${responseJson.message}`);
|
||||||
if (responseJson?.forecast && Array.isArray(responseJson?.forecast)) {
|
if (responseJson?.forecast && Array.isArray(responseJson?.forecast)) {
|
||||||
@ -254,7 +254,10 @@ const ForecastTab = ({ onGoToAdmin }) => {
|
|||||||
NEQCONFIG: techObj.id,
|
NEQCONFIG: techObj.id,
|
||||||
NEQUIPDSCMML: model.NRN,
|
NEQUIPDSCMML: model.NRN,
|
||||||
CFORECAST: {
|
CFORECAST: {
|
||||||
VALUE: object2Base64XML(responseJson, { arrayNodeName: "forecast" }),
|
VALUE: object2Base64XML(
|
||||||
|
{ XDATA: { XFORECAST: responseJson.forecast.map(f => ({ STIME: f.time, SVALUE: f.value })) } },
|
||||||
|
{ arrayNodeName: "XFORECAST" }
|
||||||
|
),
|
||||||
SDATA_TYPE: SERV_DATA_TYPE_CLOB
|
SDATA_TYPE: SERV_DATA_TYPE_CLOB
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -269,10 +272,11 @@ const ForecastTab = ({ onGoToAdmin }) => {
|
|||||||
hideLoader();
|
hideLoader();
|
||||||
showMsgErr(e.message);
|
showMsgErr(e.message);
|
||||||
executeStored({
|
executeStored({
|
||||||
stored: "UDO_PKG_EQUIPTCF.EQCONFIG_THOBJ_FORECAST_EPLG",
|
stored: "UDO_PKG_EQUIPTCF.EQCONFIG_THOBJ_FORECAST_BCLR",
|
||||||
args: {
|
args: {
|
||||||
NDATASET_IDENT: res.outParameters.NDATASET_IDENT,
|
NDATASET_IDENT: res.outParameters.NDATASET_IDENT,
|
||||||
NDATASET_CONFIG_IDENT: res.outParameters.NDATASET_CONFIG_IDENT
|
NDATASET_CONFIG_IDENT: res.outParameters.NDATASET_CONFIG_IDENT,
|
||||||
|
NREQUEST_CONFIG_IDENT: res.outParameters.NREQUEST_CONFIG_IDENT
|
||||||
},
|
},
|
||||||
loader: false,
|
loader: false,
|
||||||
showErrorMessage: false,
|
showErrorMessage: false,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user