diff --git a/db/UDO_PKG_EQUIPDS.pck b/db/UDO_PKG_EQUIPDS.pck index 073b616..65524b9 100644 --- a/db/UDO_PKG_EQUIPDS.pck +++ b/db/UDO_PKG_EQUIPDS.pck @@ -102,19 +102,33 @@ create or replace package UDO_PKG_EQUIPDS as NEQUIPDSCMML in number -- Рег. номер модели класса оборудования выборки данных ); - /* Состояние моделей по единице оборудования */ + /* Состояние "Выборки данных оборудования (классы оборудования, модели)" по единице оборудования */ function CMML_STATUS_BY_EQCONFIG ( NEQCONFIG in number -- Рег. номер позиции состава оборудования ) return number; -- Код действия с моделью (0 - нет моделей, 1 - есть модели в процессе обучения, 2 - есть обученные модели) - /* Список моделей по единице оборудования */ + /* Список "Выборки данных оборудования (классы оборудования, модели)" по единице оборудования */ procedure CMML_LIST_BY_EQCONFIG ( NEQCONFIG in number, -- Рег. номер позиции состава оборудования COUT out clob -- Сериализованная таблица данных ); + /* Формирование демо-прогноза */ + procedure CMMLH_DEMO_BUILD + ( + STASK in varchar2, -- Задача + COUT out clob -- Данные демо-прогноза + ); + + /* Список "Выборки данных оборудования (классы оборудования, модели, история запросов)" по единице оборудования */ + procedure CMMLH_LIST_BY_EQCONFIG + ( + NEQCONFIG in number, -- Рег. номер позиции состава оборудования + COUT out clob -- Сериализованная таблица данных + ); + end UDO_PKG_EQUIPDS; / create or replace package body UDO_PKG_EQUIPDS as @@ -592,7 +606,7 @@ text="Проверка прав доступа на работу с ""Выбор end loop; end CMML_SEND_RQ; - /* Состояние моделей по единице оборудования */ + /* Состояние "Выборки данных оборудования (классы оборудования, модели)" по единице оборудования */ function CMML_STATUS_BY_EQCONFIG ( NEQCONFIG in number -- Рег. номер позиции состава оборудования @@ -620,7 +634,7 @@ text="Проверка прав доступа на работу с ""Выбор return NRES; end CMML_STATUS_BY_EQCONFIG; - /* Список моделей по единице оборудования */ + /* Список "Выборки данных оборудования (классы оборудования, модели)" по единице оборудования */ procedure CMML_LIST_BY_EQCONFIG ( NEQCONFIG in number, -- Рег. номер позиции состава оборудования @@ -715,5 +729,153 @@ text="Проверка прав доступа на работу с ""Выбор COUT := PKG_P8PANELS_VISUAL.TDATA_GRID_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => 1); end CMML_LIST_BY_EQCONFIG; + /* Формирование демо-прогноза */ + procedure CMMLH_DEMO_BUILD + ( + STASK in varchar2, -- Задача + COUT out clob -- Данные демо-прогноза + ) + is + RCH PKG_P8PANELS_VISUAL.TCHART; -- График + RCH_DS PKG_P8PANELS_VISUAL.TCHART_DATASET; -- Набор данных + DMONTH date; -- Месяц прогноза + begin + /* Сформируем заголовок графика */ + RCH := PKG_P8PANELS_VISUAL.TCHART_MAKE(STYPE => PKG_P8PANELS_VISUAL.SCHART_TYPE_LINE, + STITLE => 'Прогноз на 5 месяцев', + SLGND_POS => PKG_P8PANELS_VISUAL.SCHART_LGND_POS_RIGHT); + /* Сформируем набор данных */ + RCH_DS := PKG_P8PANELS_VISUAL.TCHART_DATASET_MAKE(SCAPTION => STASK); + /* Генерируем случайные данные */ + for I in 1 .. 5 + loop + /* Добавим метку для месяца */ + DMONTH := ADD_MONTHS(sysdate, I); + PKG_P8PANELS_VISUAL.TCHART_ADD_LABEL(RCHART => RCH, + SLABEL => F_GET_MONTH(NVALUE => EXTRACT(month from DMONTH)) || ' ' || + TO_CHAR(DMONTH, 'yyyy')); + /* Добавим месяц в набор данных */ + PKG_P8PANELS_VISUAL.TCHART_DATASET_ADD_ITEM(RDATASET => RCH_DS, NVALUE => ROUND(DBMS_RANDOM.VALUE(1, 100))); + end loop; + /* Добавим набор данных в график */ + PKG_P8PANELS_VISUAL.TCHART_ADD_DATASET(RCHART => RCH, RDATASET => RCH_DS); + /* Сериализуем описание */ + COUT := PKG_P8PANELS_VISUAL.TCHART_TO_XML(RCHART => RCH, NINCLUDE_DEF => 1); + end CMMLH_DEMO_BUILD; + + /* Извлечение прогноза из демо-данных */ + function CMMLH_DEMO_FORECAST_PARSE + ( + CFORECAST in clob -- Данные демо-прогноза + ) return number -- Прогнозное значение + is + XDOC PKG_XPATH.TDOCUMENT; -- Десериализованный демо-прогноз + XROOT PKG_XPATH.TNODE; -- Корневой элемент данных + begin + /* Разбираем демо-даные */ + XDOC := PKG_XPATH.PARSE_FROM_CLOB(LCXML => CFORECAST); + /* Извлекаем корневой элемент */ + XROOT := PKG_XPATH.ROOT_NODE(RDOCUMENT => XDOC); + /* Возвращаем значение за ближайший месяц */ + return PKG_XPATH.VALUE_NUM(RNODE => PKG_XPATH.SINGLE_NODE(RPARENT_NODE => XROOT, + SPATTERN => 'XDATA/XCHART/datasets/data')); + exception + when others then + return null; + end CMMLH_DEMO_FORECAST_PARSE; + + /* Список "Выборки данных оборудования (классы оборудования, модели, история запросов)" по единице оборудования */ + procedure CMMLH_LIST_BY_EQCONFIG + ( + NEQCONFIG in number, -- Рег. номер позиции состава оборудования + COUT out clob -- Сериализованная таблица данных + ) + is + RDG PKG_P8PANELS_VISUAL.TDATA_GRID; -- Описание таблицы + RDG_ROW PKG_P8PANELS_VISUAL.TROW; -- Строка таблицы + begin + /* Инициализируем таблицу данных */ + RDG := PKG_P8PANELS_VISUAL.TDATA_GRID_MAKE(); + /* Добавляем в таблицу описание колонок */ + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NRN', + SCAPTION => 'Рег. номер', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'SRQ_AUTHID', + SCAPTION => 'Пользователь', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'SRQ_DATE', + SCAPTION => 'Дата/время запроса', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'SEQUIPDS_CODE', + SCAPTION => 'Выборка', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'SEQUIPDSCMML_TASK', + SCAPTION => 'Задача', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + SHINT => UDO_PKG_EQUIPDS_BASE.CMML_TASK_HINT()); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NEQUIPDSCMML_PRECISION_F', + SCAPTION => 'Точность (факт)', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NFORECAST', + SCAPTION => 'Прогноз', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, + SHINT => 'Опасность - вероятность сбоя более 60%.
' || + 'Внимание - вероятность сбоя от 30% до 60%
' || + 'В норме - вероятность сбоев менее 30%'); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'SFORECAST', + SCAPTION => 'Данные прогноза', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + BVISIBLE => false); + /* Обходим данные */ + for C in (select T.RN NRN, + T.RQ_AUTHID SRQ_AUTHID, + TO_CHAR(T.RQ_DATE, 'dd.mm.yyyy hh24:mi:ss') SRQ_DATE, + DS.CODE SEQUIPDS_CODE, + ML.TASK SEQUIPDSCMML_TASK, + ML.PRECISION_F NEQUIPDSCMML_PRECISION_F, + null NFORECAST, + null SFORECAST, + T.FORECAST BFORECAST + from UDO_T_EQUIPDSCMMLH T, + UDO_T_EQUIPDSCMML ML, + UDO_T_EQUIPDSCM CM, + UDO_T_EQUIPDS DS + where T.EQCONFIG = NEQCONFIG + and T.PRN = ML.RN + and ML.PRN = CM.RN + and CM.PRN = DS.RN + order by T.RN desc) + loop + /* Конвертируем данные прогноза */ + C.SFORECAST := BLOB2CLOB(LBDATA => C.BFORECAST); + /* Извлекаем прогноз */ + C.NFORECAST := CMMLH_DEMO_FORECAST_PARSE(CFORECAST => C.SFORECAST); + /* Добавляем колонки с данными */ + PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NRN', NVALUE => C.NRN, BCLEAR => true); + PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SRQ_AUTHID', SVALUE => C.SRQ_AUTHID); + PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SRQ_DATE', SVALUE => C.SRQ_DATE); + PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SEQUIPDS_CODE', SVALUE => C.SEQUIPDS_CODE); + PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SEQUIPDSCMML_TASK', SVALUE => C.SEQUIPDSCMML_TASK); + PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, + SNAME => 'NEQUIPDSCMML_PRECISION_F', + NVALUE => C.NEQUIPDSCMML_PRECISION_F); + PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NFORECAST', NVALUE => C.NFORECAST); + PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SFORECAST', SVALUE => C.SFORECAST); + /* Добавляем строку в таблицу */ + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW); + end loop; + /* Сериализуем описание */ + COUT := PKG_P8PANELS_VISUAL.TDATA_GRID_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => 1); + end CMMLH_LIST_BY_EQCONFIG; + end UDO_PKG_EQUIPDS; / diff --git a/db/UDO_PKG_EQUIPDS_BASE.pck b/db/UDO_PKG_EQUIPDS_BASE.pck index e916612..cecc019 100644 --- a/db/UDO_PKG_EQUIPDS_BASE.pck +++ b/db/UDO_PKG_EQUIPDS_BASE.pck @@ -147,6 +147,37 @@ create or replace package UDO_PKG_EQUIPDS_BASE as function CMML_TASK_HINT return varchar2; -- Подсказка для задачи + /* Базовое добавление "Выборки данных оборудования (классы оборудования, модели, история запросов)" */ + procedure CMMLH_INS + ( + NPRN in number, -- Родитель + NEQCONFIG in number, -- Рег. номер технического объекта + SRQ_AUTHID in varchar2, -- Пользователь, выполнивший запрос + DRQ_DATE in date, -- Дата/время запроса + BRQ in blob, -- Параметры запроса + NRN out number -- Регистрационный номер + ); + + /* Базовое удаление "Выборки данных оборудования (классы оборудования, модели, история запросов)" */ + procedure CMMLH_DEL + ( + NRN in number -- Регистрационный номер + ); + + /* Базовая установка данных прогноза "Выборки данных оборудования (классы оборудования, файлы данных, история запросов)" */ + procedure CMMLH_SET_FORECAST + ( + NRN in number, -- Регистрационный номер + BFORECAST in blob -- Данные прогноза + ); + + /* Базовая установка идентификатора очереди обмена "Выборки данных оборудования (классы оборудования, файлы данных, история запросов)" */ + procedure CMMLH_SET_EXSQUEUE + ( + NRN in number, -- Регистрационный номер + NEXSQUEUE in number -- Идентификатор очереди обмена + ); + end UDO_PKG_EQUIPDS_BASE; / create or replace package body UDO_PKG_EQUIPDS_BASE as @@ -467,6 +498,62 @@ create or replace package body UDO_PKG_EQUIPDS_BASE as begin return 'TCF - Оценка технического состояния (Technical Condition Forecast)
' || 'RUL - Прогнозирование остаточного ресурса (Remaining Useful Life)
' || 'FP - Прогнозирование отказа (Failure Predict)'; end CMML_TASK_HINT; + + /* Базовое добавление "Выборки данных оборудования (классы оборудования, модели, история запросов)" */ + procedure CMMLH_INS + ( + NPRN in number, -- Родитель + NEQCONFIG in number, -- Рег. номер технического объекта + SRQ_AUTHID in varchar2, -- Пользователь, выполнивший запрос + DRQ_DATE in date, -- Дата/время запроса + BRQ in blob, -- Параметры запроса + NRN out number -- Регистрационный номер + ) + is + begin + /* Формируем рег. номер */ + NRN := GEN_ID(); + /* Добавляем запись */ + insert into UDO_T_EQUIPDSCMMLH + (RN, PRN, EQCONFIG, RQ_AUTHID, RQ_DATE, RQ, FORECAST, EXSQUEUE) + values + (NRN, NPRN, NEQCONFIG, SRQ_AUTHID, DRQ_DATE, BRQ, null, null); + end CMMLH_INS; + + /* Базовое удаление "Выборки данных оборудования (классы оборудования, модели, история запросов)" */ + procedure CMMLH_DEL + ( + NRN in number -- Регистрационный номер + ) + is + begin + /* Удалим запись */ + delete from UDO_T_EQUIPDSCMMLH T where T.RN = NRN; + end CMMLH_DEL; + + /* Базовая установка данных прогноза "Выборки данных оборудования (классы оборудования, файлы данных, история запросов)" */ + procedure CMMLH_SET_FORECAST + ( + NRN in number, -- Регистрационный номер + BFORECAST in blob -- Данные прогноза + ) + is + begin + /* Установим данные ответа */ + update UDO_T_EQUIPDSCMMLH T set T.FORECAST = BFORECAST where T.RN = NRN; + end CMMLH_SET_FORECAST; + + /* Базовая установка идентификатора очереди обмена "Выборки данных оборудования (классы оборудования, файлы данных, история запросов)" */ + procedure CMMLH_SET_EXSQUEUE + ( + NRN in number, -- Регистрационный номер + NEXSQUEUE in number -- Идентификатор очереди обмена + ) + is + begin + /* Установим идентификатор очереди обмена */ + update UDO_T_EQUIPDSCMMLH T set T.EXSQUEUE = NEXSQUEUE where T.RN = NRN; + end CMMLH_SET_EXSQUEUE; end UDO_PKG_EQUIPDS_BASE; / diff --git a/db/UDO_PKG_EQUIPTCF.pck b/db/UDO_PKG_EQUIPTCF.pck index 421bedc..858f592 100644 --- a/db/UDO_PKG_EQUIPTCF.pck +++ b/db/UDO_PKG_EQUIPTCF.pck @@ -28,6 +28,23 @@ create or replace package UDO_PKG_EQUIPTCF as NEQCONFIG in number, -- Рег. номер технического объекта COUT out clob -- Сериализованная карточка ); + + /* Отправка запроса на формирование прогноза технического объекта */ + procedure EQCONFIG_THOBJ_FORECAST + ( + NEQCONFIG in number, -- Рег. номер технического объекта + NEQUIPDSCMML in number -- Рег. номер модели + ); + + /* Формирование ремонтной ведомости для технического объекта */ + 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; / @@ -416,6 +433,109 @@ text="Проверка прав доступа при формировании /* Закрываем документ */ PKG_XMAKE.CLOSE_CURSOR(ICURSOR => NCUR); end EQCONFIG_THOBJ_CARD; + + /* Отправка запроса на формирование прогноза технического объекта */ + procedure EQCONFIG_THOBJ_FORECAST + ( + NEQCONFIG in number, -- Рег. номер технического объекта + NEQUIPDSCMML in number -- Рег. номер модели + ) + is + NEQUIPDSCMMLH PKG_STD.TREF; -- Рег. номер истории запросов модели + CDEMO clob; -- Демо-данные прогноза + begin + /* Добавляем запись истории запросов */ + UDO_PKG_EQUIPDS_BASE.CMMLH_INS(NPRN => NEQUIPDSCMML, + NEQCONFIG => NEQCONFIG, + SRQ_AUTHID => UTILIZER(), + DRQ_DATE => sysdate, + BRQ => null, + NRN => NEQUIPDSCMMLH); + /* Добавим демо-данные */ + for C in (select T.TASK from UDO_T_EQUIPDSCMML T where T.RN = NEQUIPDSCMML) + loop + UDO_PKG_EQUIPDS.CMMLH_DEMO_BUILD(STASK => C.TASK, COUT => CDEMO); + UDO_PKG_EQUIPDS_BASE.CMMLH_SET_FORECAST(NRN => NEQUIPDSCMMLH, BFORECAST => CLOB2BLOB(LCDATA => CDEMO)); + end loop; + end EQCONFIG_THOBJ_FORECAST; + + /* Формирование ремонтной ведомости для технического объекта */ + 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; -- Рег. номер сформированной ведомости + NSELECTLIST 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); + /* Добавим ведомость в список */ + NIDENT := GEN_IDENT(); + P_SELECTLIST_INSERT(NIDENT => NIDENT, + NDOCUMENT => NEQRPSHEET, + SUNITCODE => 'EquipRepairSheets', + NRN => NSELECTLIST); + end EQCONFIG_THOBJ_MAKE_EQRPSHEET; end UDO_PKG_EQUIPTCF; / diff --git a/db/UDO_T_EQUIPDSCMMLH.sql b/db/UDO_T_EQUIPDSCMMLH.sql new file mode 100644 index 0000000..fd9dced --- /dev/null +++ b/db/UDO_T_EQUIPDSCMMLH.sql @@ -0,0 +1,27 @@ +/* Выборки данных оборудования (классы оборудования, модели, история запросов) */ +create table UDO_T_EQUIPDSCMMLH +( + /* Регистрационный номер */ + RN number(17) not null, + /* Родитель */ + PRN number(17) not null, + /* Рег. номер технического объекта */ + EQCONFIG number(17) not null, + /* Пользователь, выполнивший запрос */ + RQ_AUTHID varchar2(30) not null, + /* Дата/время запроса */ + RQ_DATE date not null, + /* Параметры запроса */ + RQ blob, + /* Данные прогноза */ + FORECAST blob, + /* Идентификатор очереди обмена */ + EXSQUEUE number(17) default null, + /* Ключи */ + 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_EQCONFIG_FK foreign key (EQCONFIG) references EQCONFIG(RN), + constraint UDO_C_EQUIPDSCMMLH_RQAUTHID_NB check (rtrim(RQ_AUTHID) is not null), + constraint UDO_C_EQUIPDSCMMLH_EXSQUEUE_FK foreign key (EXSQUEUE) references EXSQUEUE(RN), + constraint UDO_C_EQUIPDSCMMLH_UN unique (PRN, RQ_AUTHID, RQ_DATE) +); diff --git a/panels/eqs_tech_cond_forecast/admin_tab.js b/panels/eqs_tech_cond_forecast/admin_tab.js index 377d3ea..1e8192d 100644 --- a/panels/eqs_tech_cond_forecast/admin_tab.js +++ b/panels/eqs_tech_cond_forecast/admin_tab.js @@ -43,6 +43,9 @@ const REFRESH_INITIAL = { dataSelectionClassMachineModelsList: 0 }; +//Начальное состояние диалогов +const DIALOGS_INITIAL = { dataSelectionIU: false, dataSelectionClassMachineIU: false, dataSelectionClassMachineModelIU: false }; + //Стили const STYLES = { DATA_SELECTION_STACK: { alignItems: "center" }, @@ -62,7 +65,7 @@ const AdminTab = ({ dataSelection = DS_RN_DEFAULT, dataSelectionClassMachine = n const { pOnlineUserProcedure } = useContext(ApplicationСtx); //Собственное состояние - отображаемые диалоги - const [dialogs, setDialogs] = useState({ dataSelectionIU: false, dataSelectionClassMachineIU: false, dataSelectionClassMachineModelIU: false }); + const [dialogs, setDialogs] = useState(DIALOGS_INITIAL); //Собственное состояние - флаги обновления данных const [refresh, setRefresh] = useState(REFRESH_INITIAL); diff --git a/panels/eqs_tech_cond_forecast/admin_tab_layout.js b/panels/eqs_tech_cond_forecast/admin_tab_layout.js index d4557d5..0e40801 100644 --- a/panels/eqs_tech_cond_forecast/admin_tab_layout.js +++ b/panels/eqs_tech_cond_forecast/admin_tab_layout.js @@ -7,7 +7,7 @@ //Подключение библиотек //--------------------- -import React, { useState, useContext, useEffect } from "react"; //Классы React +import React, { useState, useContext } from "react"; //Классы React import PropTypes from "prop-types"; //Контроль свойств компонента import { Box, @@ -28,15 +28,13 @@ import { DialogTitle, DialogContent, DialogActions, - Input, - InputAdornment, IconButton, Icon } from "@mui/material"; //Интерфейсные компоненты import { useTheme } from "@mui/material/styles"; //Темы оформления import { ApplicationСtx } from "../../context/application"; //Контекст приложения import { BUTTONS } from "../../../app.text"; //Текстовые ресурсы и константы -import { APP_BAR_HEIGHT, TABS_HEIGHT, SCROLL_STYLES, formatModelStateValue } from "./eqs_tech_cond_forecast_lyaout"; //Общие вспомогательные компоненты и вёрстка +import { APP_BAR_HEIGHT, TABS_HEIGHT, SCROLL_STYLES, formatModelStateValue, IUDFormTextField } from "./eqs_tech_cond_forecast_lyaout"; //Общие вспомогательные компоненты и вёрстка import { P8PDataGrid, P8P_DATA_GRID_SIZE } from "../../components/p8p_data_grid"; //Таблица данных import { P8P_DATA_GRID_CONFIG_PROPS } from "../../config_wrapper"; //Подключение компонентов к настройкам приложения import { DS_RN_DEFAULT } from "./admin_tab_hooks"; //Вспомогательные хуки @@ -104,85 +102,6 @@ const STYLES = { //Вспомогательные функции и компоненты //------------------------------------ -//Поле ввода из словаря -const IUDFormTextField = ({ elementCode, elementValue, labelText, onChange, dictionary, list, ...other }) => { - //Значение элемента - const [value, setValue] = useState(elementValue); - - //При получении нового значения из вне - useEffect(() => { - setValue(elementValue); - }, [elementValue]); - - //Выбор значения из словаря - const handleDictionaryClick = () => - dictionary ? dictionary(res => (res ? res.map(i => handleChange({ target: { name: i.name, value: i.value } })) : null)) : null; - - //Изменение значения элемента - const handleChange = e => { - console.log(e.target.name, e.target.value); - setValue(e.target.value); - if (onChange) onChange(e.target.name, e.target.value); - }; - - //Генерация содержимого - return ( - - - {list ? ( - <> - {labelText} - - - ) : ( - <> - {labelText} - - - list - - - ) : null - } - onChange={handleChange} - /> - - )} - - - ); -}; - -//Контроль свойств - Поле ввода из словаря -IUDFormTextField.propTypes = { - elementCode: PropTypes.string.isRequired, - elementValue: PropTypes.string, - labelText: PropTypes.string.isRequired, - onChange: PropTypes.func, - dictionary: PropTypes.func, - list: PropTypes.array -}; - //Кнопка с дополнительной подписью const ExtraCaptionButton = ({ caption, title, subtitle, maxWidth, onClick, theme }) => { //При нажатии на кнопку diff --git a/panels/eqs_tech_cond_forecast/eqs_tech_cond_forecast_lyaout.js b/panels/eqs_tech_cond_forecast/eqs_tech_cond_forecast_lyaout.js index 45b9516..2b012d2 100644 --- a/panels/eqs_tech_cond_forecast/eqs_tech_cond_forecast_lyaout.js +++ b/panels/eqs_tech_cond_forecast/eqs_tech_cond_forecast_lyaout.js @@ -7,9 +7,9 @@ //Подключение библиотек //--------------------- -import React from "react"; //Классы React +import React, { useState, useEffect } from "react"; //Классы React import PropTypes from "prop-types"; //Контроль свойств компонента -import { Box, Stack, Icon } from "@mui/material"; //Интерфейсные компоненты +import { Box, Stack, Icon, Input, InputAdornment, FormControl, Select, InputLabel, MenuItem, IconButton } from "@mui/material"; //Интерфейсные компоненты //--------- //Константы @@ -62,10 +62,10 @@ const formatModelStateValue = (theme, value, err) => { value == 0 ? ["Зарегистрирована", "app_registration", null] : value == 1 - ? ["Обрабатывается внешней системой", "manage_history", theme.palette.warning.main] + ? ["Обучается", "manage_history", theme.palette.warning.main] : value == 2 - ? ["Успешно обработана внешней системой", "check_circle", theme.palette.primary.main] - : [`Ошибка обработки внешней системой: ${err}`, "error", theme.palette.error.main]; + ? ["Обучена", "check_circle", theme.palette.primary.main] + : [`Ошибка обучения: ${err}`, "error", theme.palette.error.main]; return ( {icon} @@ -84,8 +84,98 @@ TabPanel.propTypes = { children: PropTypes.element }; +//Поле ввода формы +const IUDFormTextField = ({ elementCode, elementValue, labelText, onChange, dictionary, list, type, ...other }) => { + //Значение элемента + const [value, setValue] = useState(elementValue); + + //При получении нового значения из вне + useEffect(() => { + setValue(elementValue); + }, [elementValue]); + + //Выбор значения из словаря + const handleDictionaryClick = () => + dictionary ? dictionary(res => (res ? res.map(i => handleChange({ target: { name: i.name, value: i.value } })) : null)) : null; + + //Изменение значения элемента + const handleChange = e => { + setValue(e.target.value); + if (onChange) onChange(e.target.name, e.target.value); + }; + + //Генерация содержимого + return ( + + + {list ? ( + <> + {labelText} + + + ) : ( + <> + {labelText} + + + list + + + ) : null + } + {...(type ? { type } : {})} + onChange={handleChange} + /> + + )} + + + ); +}; + +//Контроль свойств - Поле ввода формы +IUDFormTextField.propTypes = { + elementCode: PropTypes.string.isRequired, + elementValue: PropTypes.string, + labelText: PropTypes.string.isRequired, + onChange: PropTypes.func, + dictionary: PropTypes.func, + list: PropTypes.array, + type: PropTypes.string +}; + //---------------- //Интерфейс модуля //---------------- -export { MODES, APP_BAR_HEIGHT, TABS_HEIGHT, TABLE_MORE_HEIGHT, TABLE_FILTERS_HEIGHT, SCROLL_STYLES, formatModelStateValue, TabPanel }; +export { + MODES, + APP_BAR_HEIGHT, + TABS_HEIGHT, + TABLE_MORE_HEIGHT, + TABLE_FILTERS_HEIGHT, + SCROLL_STYLES, + formatModelStateValue, + TabPanel, + IUDFormTextField +}; diff --git a/panels/eqs_tech_cond_forecast/forecast_tab.js b/panels/eqs_tech_cond_forecast/forecast_tab.js index e45aa2e..edb2ec1 100644 --- a/panels/eqs_tech_cond_forecast/forecast_tab.js +++ b/panels/eqs_tech_cond_forecast/forecast_tab.js @@ -13,15 +13,18 @@ import { Box, Grid } from "@mui/material"; //Интерфейсные компо import { RichTreeView } from "@mui/x-tree-view/RichTreeView"; //Дерево import { useTreeViewApiRef } from "@mui/x-tree-view/hooks/useTreeViewApiRef"; //API дерева import { MessagingСtx } from "../../context/messaging"; //Контекст сообщений +import { BackEndСtx } from "../../context/backend"; //Контекст взаимодействия с серверомs +import { ApplicationСtx } from "../../context/application"; //Контекст приложения import { P8PDataGrid, P8P_DATA_GRID_SIZE } from "../../components/p8p_data_grid"; //Таблица данных import { P8P_DATA_GRID_CONFIG_PROPS } from "../../config_wrapper"; //Подключение компонентов к настройкам приложения import { APP_BAR_HEIGHT, TABS_HEIGHT, TABLE_FILTERS_HEIGHT, TABLE_MORE_HEIGHT, SCROLL_STYLES } from "./eqs_tech_cond_forecast_lyaout"; //Общие Вспомогательные компоненты и вёрстка -import { TechObjCard, eqConfigTechObjTableValueFormatter, eqConfigTechObjTableDataCellRender } from "./forecast_tab_layout"; //Вспомогательные компоненты и вёрстка +import { TechObjCard, eqConfigTechObjTableValueFormatter, eqConfigTechObjTableDataCellRender, TechObjMakeEqRpSheet } from "./forecast_tab_layout"; //Вспомогательные компоненты и вёрстка import { useEqConfigTree, useEqConfigTechObjTable, useEqConfigTechObjCard, useTechObjModelsList, + useTechObjForecastHistList, findTreeItem, needLoadLevel } from "./forecast_tab_hooks"; //Вспомогательные хуки @@ -30,6 +33,14 @@ import { //Константы //--------- +//Начальное состояние флагов обновления +const REFRESH_INITIAL = { + techObjForecastHistList: 0 +}; + +//Начальное состояние диалогов +const DIALOGS_INITIAL = { makeEqRpSheet: false }; + //Стили const STYLES = { LEFT_SIDE_GRID: {}, @@ -59,9 +70,15 @@ const TECH_OBJ_SPEC_INIT = { parent: null, filters: [], orders: [], pageNumber: //Закладка прогнозирования const ForecastTab = ({ onGoToAdmin }) => { + //Подключение к контексту взаимодействия с сервером + const { executeStored } = useContext(BackEndСtx); + //Подключение к контексту сообщений const { InlineMsgInfo } = useContext(MessagingСtx); + //Подключение к контексту приложения + const { pOnlineShowUnit } = useContext(ApplicationСtx); + //Подключение к API дерева const apiRef = useTreeViewApiRef(); @@ -71,9 +88,15 @@ const ForecastTab = ({ onGoToAdmin }) => { //Собственное состояние - спецификация технических объектов const [techObjSpec, setTechObjSpec] = useState({ ...TECH_OBJ_SPEC_INIT }); - //Собственное состояния - карточка технического объекта + //Собственное состояния - карточка технического объекта - 11984229 const [techObjCardId, setTechObjCardId] = useState(null); + //Собственное состояние - отображаемые диалоги + const [dialogs, setDialogs] = useState(DIALOGS_INITIAL); + + //Собственное состояния - флаги перезагрузки + const [refresh, setRefresh] = useState(REFRESH_INITIAL); + //Загрузчик веток дерева const { eQconfigTree } = useEqConfigTree(loadingTreeItem); @@ -89,7 +112,10 @@ const ForecastTab = ({ onGoToAdmin }) => { const { techObjCard, techObjCardIsLoading } = useEqConfigTechObjCard(techObjCardId); //Загрузчик моделей выбранного технического объекта - const { techObjModelsList, techObjModelsListIsLoading } = useTechObjModelsList(techObjCardId); + const { techObjModelsList } = useTechObjModelsList(techObjCardId); + + // + const { techObjForecastHistList } = useTechObjForecastHistList(techObjCardId, refresh.techObjForecastHistList); //Обработка развёртывания/свёртывания уровня дерева const handleTreeItemExpansionToggle = (event, itemId, isExpanded) => @@ -128,9 +154,36 @@ const ForecastTab = ({ onGoToAdmin }) => { //При переходе к закладке администрирования из карточки технического объекта const handleTechObjeCardGoToModel = model => (onGoToAdmin ? onGoToAdmin(model.NEQUIPDS, model.NEQUIPDSCM) : null); + //При запросе прогноза по модели из карточки технического объекта + const handleTechObjeCardGetPrediction = async model => { + await executeStored({ stored: "UDO_PKG_EQUIPTCF.EQCONFIG_THOBJ_FORECAST", args: { NEQCONFIG: techObjCardId, NEQUIPDSCMML: model.NRN } }); + setRefresh(pv => ({ ...pv, techObjForecastHistList: pv.techObjForecastHistList + 1 })); + }; + //При закрытии карточки технического объекта const handleTechObjeCardClose = () => setTechObjCardId(null); + //При нажатии на "Ремонтировать" в карточке технического объекта + const handleTechObjeCardMakeEqRpSheet = () => setDialogs(pv => ({ ...pv, makeEqRpSheet: true })); + + //При нажатии "ОК" в диалоге формирования ремонтной ведомости + const handleTechObjMakeEqRpSheetOk = async values => { + const data = await executeStored({ + stored: "UDO_PKG_EQUIPTCF.EQCONFIG_THOBJ_MAKE_EQRPSHEET", + args: { + NEQCONFIG: techObjCardId, + SACATALOG: values.acatalog, + SEQTECSRVKIND: values.eQTecSrvKind, + DPLANDATE_FROM: new Date(values.planDateFrom) + } + }); + setDialogs(pv => ({ ...pv, makeEqRpSheet: false })); + pOnlineShowUnit({ unitCode: "EquipRepairSheets", showMethod: "main_selected", inputParameters: [{ name: "in_Ident", value: data.NIDENT }] }); + }; + + //При нажитии "Отмена" в диалоге формирования ремонтной ведомости + const handleTechObjMakeEqRpSheetCancel = () => setDialogs(pv => ({ ...pv, makeEqRpSheet: false })); + //Текст при отсутствии данных в списке технических объектов const noDataFoundText = techObjsDataGridIsLoading || !techObjsDataGrid.init @@ -142,6 +195,7 @@ const ForecastTab = ({ onGoToAdmin }) => { //Генерация содержимого return (
+ {dialogs.makeEqRpSheet ? : null} @@ -155,12 +209,15 @@ const ForecastTab = ({ onGoToAdmin }) => { {techObjCardId ? ( - !techObjCardIsLoading && !techObjModelsListIsLoading ? ( + !techObjCardIsLoading ? ( ) : null ) : techObjsDataGrid.init ? ( diff --git a/panels/eqs_tech_cond_forecast/forecast_tab_hooks.js b/panels/eqs_tech_cond_forecast/forecast_tab_hooks.js index 3cb34c1..61d3ccd 100644 --- a/panels/eqs_tech_cond_forecast/forecast_tab_hooks.js +++ b/panels/eqs_tech_cond_forecast/forecast_tab_hooks.js @@ -225,8 +225,59 @@ const useTechObjModelsList = (id, refresh) => { return { techObjModelsList: data, techObjModelsListIsLoading: isLoading }; }; +//Загрузка истории запросов к модели единицы оборудования +const useTechObjForecastHistList = (id, refresh) => { + //Собственное состояние - флаг загрузки + const [isLoading, setLoading] = useState(false); + + //Собственное состояние - таблица данных + const [data, setData] = useState({ + init: false, + columnsDef: [], + rows: [] + }); + + //Подключение к контексту взаимодействия с сервером + const { executeStored } = useContext(BackEndСtx); + + //Загрузка данных при изменении зависимостей + useEffect(() => { + const loadData = async () => { + try { + setLoading(true); + const data = await executeStored({ + stored: "UDO_PKG_EQUIPDS.CMMLH_LIST_BY_EQCONFIG", + args: { NEQCONFIG: id }, + respArg: "COUT", + loader: false + }); + setData(pv => ({ + ...pv, + columnsDef: [...data.XCOLUMNS_DEF], + rows: [...(data.XROWS || [])], + init: true + })); + } finally { + setLoading(false); + } + }; + if (id) loadData(); + }, [id, refresh, executeStored]); + + //Вернём данные + return { techObjForecastHistList: data, techObjForecastHistListIsLoading: isLoading }; +}; + //---------------- //Интерфейс модуля //---------------- -export { useEqConfigTree, useEqConfigTechObjTable, useEqConfigTechObjCard, findTreeItem, needLoadLevel, useTechObjModelsList }; +export { + useEqConfigTree, + useEqConfigTechObjTable, + useEqConfigTechObjCard, + findTreeItem, + needLoadLevel, + useTechObjModelsList, + useTechObjForecastHistList +}; diff --git a/panels/eqs_tech_cond_forecast/forecast_tab_layout.js b/panels/eqs_tech_cond_forecast/forecast_tab_layout.js index 4803d16..f8022d8 100644 --- a/panels/eqs_tech_cond_forecast/forecast_tab_layout.js +++ b/panels/eqs_tech_cond_forecast/forecast_tab_layout.js @@ -7,15 +7,33 @@ //Подключение библиотек //--------------------- -import React from "react"; //Классы React +import React, { useState, useEffect, useContext } from "react"; //Классы React import PropTypes from "prop-types"; //Контроль свойств компонента -import { Stack, Icon, Box, Card, CardContent, Typography, CardActions, Button, IconButton, Divider } from "@mui/material"; //Интерфейсные компоненты +import { + Stack, + Icon, + Box, + Card, + CardContent, + Typography, + CardActions, + Button, + IconButton, + Divider, + Link, + Dialog, + DialogTitle, + DialogContent, + DialogActions +} from "@mui/material"; //Интерфейсные компоненты import { useTheme } from "@mui/material/styles"; //Темы оформления +import { ApplicationСtx } from "../../context/application"; //Контекст приложения +import { BUTTONS } from "../../../app.text"; //Текстовые ресурсы и константы import { P8PDataGrid, P8P_DATA_GRID_SIZE } from "../../components/p8p_data_grid"; //Таблица данных import { P8P_DATA_GRID_CONFIG_PROPS } from "../../config_wrapper"; //Подключение компонентов к настройкам приложения -import { formatDateRF } from "../../core/utils"; //Вспомогательные функции -import { SCROLL_STYLES, formatModelStateValue } from "./eqs_tech_cond_forecast_lyaout"; //Общие вспомогательные компоненты и вёрстка -import { Link } from "react-router-dom"; +import { formatDateRF, xml2JSON } from "../../core/utils"; //Вспомогательные функции +import { SCROLL_STYLES, formatModelStateValue, IUDFormTextField } from "./eqs_tech_cond_forecast_lyaout"; //Общие вспомогательные компоненты и вёрстка +import { P8PChart } from "../../components/p8p_chart"; //График //--------- //Константы @@ -28,7 +46,13 @@ const STYLES = { EQ_ML_TABLE: { maxHeight: "200px", ...SCROLL_STYLES - } + }, + EQ_FORECAST_TABLE: { + maxHeight: "200px", + ...SCROLL_STYLES + }, + EQ_FORECAST_DETAIL_DIALOG: { maxWidth: "600px" }, + EQ_FORECAST_DETAIL_CHART: { width: "550px", display: "flex", justifyContent: "center" } }; //------------------------------------ @@ -48,7 +72,7 @@ const techObjCardModelsTableHeadCellRender = ({ columnDef }) => { } }; -//Форматирование колонок таблицы моделей класса оборудования выборки данных +//Форматирование колонок таблицы моделей единицы оборудования const techObjCardModelsTableDataCellRender = ({ row, columnDef, theme, onGoToModel, onGetPrediction }) => { switch (columnDef.name) { case "SNEQUIPDS": @@ -79,15 +103,71 @@ const techObjCardModelsTableDataCellRender = ({ row, columnDef, theme, onGoToMod } }; +//Форматирование колонок таблицы истории прогнозов класса оборудования выборки данных +const techObjCardForecastListTableDataCellRender = ({ row, columnDef, onShowForecastDetail }) => { + switch (columnDef.name) { + case "NFORECAST": + return { + data: ( + + ) + }; + } +}; + +//Детали прогноза +const ForecastDetail = ({ date, forecast, onClose }) => { + //Собственное состояние - график + const [chart, setChart] = useState({ loaded: false, labels: [], datasets: [] }); + + //При подключении к странице + useEffect(() => { + const loadChart = async () => { + const chart = await xml2JSON({ xmlDoc: forecast }); + console.log(chart); + setChart(pv => ({ ...pv, loaded: true, ...chart.XDATA.XCHART })); + }; + loadChart(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + //Генерация содержимого + return ( + (onClose ? onClose() : null)} {...STYLES.EQ_FORECAST_DETAIL_DIALOG}> + {`Детали прогноза от ${date}`} + {chart.loaded ? : null} + + + + + ); +}; + +//Контроль свойств - Детали прогноза +ForecastDetail.propTypes = { + date: PropTypes.string.isRequired, + forecast: PropTypes.string.isRequired, + onClose: PropTypes.func +}; + //----------- //Тело модуля //----------- //Карточка технического объекта -const TechObjCard = ({ cardData, modelsList, onClose, onGoToModel }) => { +const TechObjCard = ({ cardData, modelsList, forecastHistList, onClose, onGoToModel, onGetPrediction, onMakeEqRpSheet }) => { //Подключаемся к теме const theme = useTheme(); + //Собственное состояние + const [state, setState] = useState({ forecastDetail: null, forecastDate: null }); + //При нажатии на кнопку закрытия карточки const handleClose = () => (onClose ? onClose() : null); @@ -95,13 +175,25 @@ const TechObjCard = ({ cardData, modelsList, onClose, onGoToModel }) => { const handleGoToModelClick = model => (onGoToModel ? onGoToModel(model) : null); //При нажатии на запрос предсказания - const handleGetPredictionClick = model => { - console.log(model); + const handleGetPredictionClick = model => (onGetPrediction ? onGetPrediction(model) : null); + + //При нажатии на формирование ремонтной ведомости + const handleMakeEqRpSheetClick = () => (onMakeEqRpSheet ? onMakeEqRpSheet() : null); + + //При нажатии на отображение деталей прогноза + const handleShowForecastDetailClick = modelHist => { + setState(pv => ({ ...pv, forecastDetail: modelHist.SFORECAST, forecastDate: modelHist.SRQ_DATE })); }; + //При нажатии на закрытие деталей прогноза + const handleCloseForecastDetailClick = () => setState(pv => ({ ...pv, forecastDetail: null, forecastDate: null })); + //Генерация содержимого return ( + {state.forecastDetail ? ( + + ) : null} @@ -122,33 +214,61 @@ const TechObjCard = ({ cardData, modelsList, onClose, onGoToModel }) => { {cardData.SNAME}
- - - Модели - - - techObjCardModelsTableDataCellRender({ - ...prms, - theme, - onGoToModel: handleGoToModelClick, - onGetPrediction: handleGetPredictionClick - }) - } - /> - + {modelsList.init ? ( + <> + + + Модели + + + techObjCardModelsTableDataCellRender({ + ...prms, + theme, + onGoToModel: handleGoToModelClick, + onGetPrediction: handleGetPredictionClick + }) + } + /> + + ) : null} + {forecastHistList.init ? ( + <> + + + Прогнозы + + + techObjCardForecastListTableDataCellRender({ + ...prms, + theme, + onShowForecastDetail: handleShowForecastDetailClick + }) + } + /> + + ) : null}
- +
@@ -159,8 +279,11 @@ const TechObjCard = ({ cardData, modelsList, onClose, onGoToModel }) => { TechObjCard.propTypes = { cardData: PropTypes.object.isRequired, modelsList: PropTypes.object.isRequired, + forecastHistList: PropTypes.object.isRequired, onClose: PropTypes.func, - onGoToModel: PropTypes.func + onGoToModel: PropTypes.func, + onGetPrediction: PropTypes.func, + onMakeEqRpSheet: PropTypes.func }; //Формирование значения для колонки "Медель" таблицы технических объектов @@ -198,8 +321,81 @@ const eqConfigTechObjTableDataCellRender = ({ row, columnDef, onCMMLStatus }) => } }; +//Диалог формирование ремонтной ведомости +const TechObjMakeEqRpSheet = ({ onOk, onCancel }) => { + //Подключение к контексту приложения + const { pOnlineShowDictionary } = useContext(ApplicationСtx); + + //Собственное состояние - значения формы + const [values, setValues] = useState({ + acatalog: "", + eQTecSrvKind: "", + planDateFrom: "" + }); + + //Отработка воода значения в форму + const handleValueChanged = (name, value) => setValues(pv => ({ ...pv, [name]: value })); + + //Выбор каталога размещения ремонтной ведомости + const selectEquipRepairSheetsCatalog = (name, callBack) => { + pOnlineShowDictionary({ + unitCode: "EquipRepairSheets", + showMethod: "catalog", + callBack: res => callBack(res.success ? [{ name, value: res.outParameters.ctlgname }] : null) + }); + }; + + //Выбор вида технического обслуживания + const selectEquipTechServiceKinds = (name, callBack) => { + pOnlineShowDictionary({ + unitCode: "EquipTechServiceKinds", + callBack: res => callBack(res.success ? [{ name, value: res.outParameters.out_CODE }] : null) + }); + }; + + //Генерация содержимого + return ( + (onOk ? onCancel() : null)}> + Формирование ремонтной ведомости + + selectEquipRepairSheetsCatalog("acatalog", callBack)} + /> + selectEquipTechServiceKinds("eQTecSrvKind", callBack)} + /> + + + + + + + + ); +}; + +//Контроль свойств - Диалог формирование ремонтной ведомости +TechObjMakeEqRpSheet.propTypes = { + onOk: PropTypes.func, + onCancel: PropTypes.func +}; + //---------------- //Интерфейс модуля //---------------- -export { TechObjCard, eqConfigTechObjTableValueFormatter, eqConfigTechObjTableDataCellRender }; +export { TechObjCard, eqConfigTechObjTableValueFormatter, eqConfigTechObjTableDataCellRender, TechObjMakeEqRpSheet };