diff --git a/db/UDO_PKG_EQUIPTCF.pck b/db/UDO_PKG_EQUIPTCF.pck index 38c92a6..382df1c 100644 --- a/db/UDO_PKG_EQUIPTCF.pck +++ b/db/UDO_PKG_EQUIPTCF.pck @@ -22,6 +22,15 @@ create or replace package UDO_PKG_EQUIPTCF as COUT out clob -- Сериализованная таблица данных ); + /* Выбор графиков технического обслуживания и ремонта технического объекта */ + procedure EQCONFIG_THOBJ_SELECT_EQTCHSRV + ( + NEQTCHSRV in number := null, -- Рег. номер графика ТО и ремонтов (null - любой) + NEQCONFIG in number := null, -- Рег. номер технического объекта (null - любой) + NSTATE in number := null, -- Состояние (null - любое) + NIDENT out number -- Идентификатор списка + ); + /* Формирование карточки технического объекта */ procedure EQCONFIG_THOBJ_CARD ( @@ -36,6 +45,14 @@ create or replace package UDO_PKG_EQUIPTCF as NEQUIPDSCMML in number -- Рег. номер модели ); + /* Модификация графика ТО и ремонтов для технического объекта */ + procedure EQCONFIG_THOBJ_CHNG_EQTCHSRV + ( + NEQCONFIG in number, -- Рег. номер технического объекта + NEQTCHSRV in number, -- Рег. номер графика ТО и ремонтов + DPLANDATE_FROM in date -- Уточнённая плановая дата начала ремонта + ); + /* Формирование ремонтной ведомости для технического объекта */ procedure EQCONFIG_THOBJ_MAKE_EQRPSHEET ( @@ -390,6 +407,57 @@ text="Проверка прав доступа при формировании COUT := PKG_P8PANELS_VISUAL.TDATA_GRID_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => NINCLUDE_DEF); end EQCONFIG_THOBJ_LIST; + /* Получение даты следующего технического обслуживания технического объекта */ + function EQCONFIG_THOBJ_GET_NXTEQTCHSRV + ( + NEQCONFIG in number, -- Рег. номер технического объекта + NSTATE in number := null -- Состояние (null - любое) + ) return date -- Дата следующего технического обслуживания + is + DRES PKG_STD.TLDATE; -- Буфер для результата + begin + /* Найдем график ТО и ремонтов, утвержденный, с минимальной датой по данному тех. объекту */ + select min(T.DATEPRD_BEG) + into DRES + from EQTCHSRV T + where T.EQCONFIG_TECH = NEQCONFIG + and ((NSTATE is null) or ((NSTATE is not null) and (T.STATE = NSTATE))) + and T.DATEPRD_BEG >= sysdate; + /* Вернём результат */ + return DRES; + exception + when others then + return null; + end EQCONFIG_THOBJ_GET_NXTEQTCHSRV; + + /* Выбор графиков технического обслуживания и ремонта технического объекта */ + procedure EQCONFIG_THOBJ_SELECT_EQTCHSRV + ( + NEQTCHSRV in number := null, -- Рег. номер графика ТО и ремонтов (null - любой) + NEQCONFIG in number := null, -- Рег. номер технического объекта (null - любой) + NSTATE in number := null, -- Состояние (null - любое) + NIDENT out number -- Идентификатор списка + ) + is + NTMP PKG_STD.TREF; -- Рег. номер записи буфера отобранных + begin + /* Обходим графики по тех. объекту */ + for C in (select T.RN + from EQTCHSRV T + where ((NEQTCHSRV is null) or ((NEQTCHSRV is not null) and (T.RN = NEQTCHSRV))) + and ((NEQCONFIG is null) or ((NEQCONFIG is not null) and (T.EQCONFIG_TECH = NEQCONFIG))) + and ((NEQTCHSRV is not null) or ((NEQTCHSRV is null) and (T.DATEPRD_BEG >= sysdate))) + and ((NSTATE is null) or ((NSTATE is not null) and (T.STATE = NSTATE)))) + loop + /* Формируем идентификатор списка если необходимо */ + if (NIDENT is null) then + NIDENT := GEN_IDENT(); + end if; + /* Добавляем отобранное в список */ + P_SELECTLIST_INSERT(NIDENT => NIDENT, NDOCUMENT => C.RN, SUNITCODE => 'EquipTechServices', NRN => NTMP); + end loop; + end EQCONFIG_THOBJ_SELECT_EQTCHSRV; + /* Формирование карточки технического объекта */ procedure EQCONFIG_THOBJ_CARD ( @@ -431,6 +499,10 @@ text="Проверка прав доступа при формировании SNAME => 'DOPER_DATE', DVALUE => C.DOPER_DATE), RATTRIBUTE04 => PKG_XMAKE.ATTRIBUTE(ICURSOR => NCUR, + SNAME => 'DNEXT_EQTCHSRV', + SVALUE => TO_CHAR(EQCONFIG_THOBJ_GET_NXTEQTCHSRV(NEQCONFIG => C.NRN), + 'dd.mm.yyyy hh24:mi:ss')), + RATTRIBUTE05 => PKG_XMAKE.ATTRIBUTE(ICURSOR => NCUR, SNAME => 'SEQOBJKIND', SVALUE => C.SEQOBJKIND))); end loop; @@ -472,6 +544,79 @@ text="Проверка прав доступа при формировании end loop; end EQCONFIG_THOBJ_FORECAST; + /* Модификация графика ТО и ремонтов для технического объекта */ + procedure EQCONFIG_THOBJ_CHNG_EQTCHSRV + ( + NEQCONFIG in number, -- Рег. номер технического объекта + NEQTCHSRV in number, -- Рег. номер графика ТО и ремонтов + DPLANDATE_FROM in date -- Уточнённая плановая дата начала ремонта + ) + is + REQTCHSRV EQTCHSRV%rowtype; -- Запись графика ТО и ремонтов + RDSCMMLH UDO_T_EQUIPDSCMMLH%rowtype; -- Запись истории прогнозов + NDIFF PKG_STD.TNUMBER; -- Отклонение старой и новой дат + DDATEPRD_BEG PKG_STD.TLDATE; -- Новая дата начала + DDATEPRD_END PKG_STD.TLDATE; -- Новая дата окончания + SNOTE PKG_STD.TSTRING; -- Новое примечание + begin + /* Считаем график */ + begin + select T.* into REQTCHSRV from EQTCHSRV T where T.RN = NEQTCHSRV; + exception + when NO_DATA_FOUND then + PKG_MSG.RECORD_NOT_FOUND(NFLAG_SMART => 0, NDOCUMENT => NEQTCHSRV, SUNIT_TABLE => 'EquipTechServices'); + end; + /* Считаем запись истории прогнозов */ + begin + select T.* + into RDSCMMLH + from UDO_T_EQUIPDSCMMLH T + where T.RN = (select max(TT.RN) from UDO_T_EQUIPDSCMMLH TT where TT.EQCONFIG = NEQCONFIG); + exception + when others then + P_EXCEPTION(0, + 'Не удалось определить запись-основание истории прогнозов модели.'); + end; + /* Проверим, что из графика не сформирована ремонтная ведомость */ + if (F_DOCLINKS_LINK_OUT_DOC(SIN_UNITCODE => 'EquipTechServices', + NIN_DOCUMENT => REQTCHSRV.RN, + SOUT_UNITCODE => 'EquipRepairSheets') is not null) then + P_EXCEPTION(0, + 'Из графика ТО и ремонтов (RN: %s) уже создана ремонтная ведомость.', + TO_CHAR(REQTCHSRV.RN)); + end if; + /* Проверим, что есть на что менять */ + if (TRUNC(DPLANDATE_FROM) = TRUNC(REQTCHSRV.DATEPRD_BEG)) then + P_EXCEPTION(0, + 'Выбранный график ТО и ремонтов уже запланирован на %s', + TO_CHAR(DPLANDATE_FROM, 'dd.mm.yyyy')); + end if; + /* Определим отклонение и новые даты графика */ + NDIFF := DPLANDATE_FROM - REQTCHSRV.DATEPRD_BEG; + DDATEPRD_BEG := REQTCHSRV.DATEPRD_BEG + NDIFF; + DDATEPRD_END := REQTCHSRV.DATEPRD_END + NDIFF; + /* Формируем новое примечание */ + SNOTE := 'Автоматически перенесён с "' || TO_CHAR(REQTCHSRV.DATEPRD_BEG, 'dd.mm.yyyy hh24:mi:ss') || '" на "' || + TO_CHAR(DDATEPRD_BEG, 'dd.mm.yyyy hh24:mi:ss') || '" на основании прогноза от "' || + TO_CHAR(RDSCMMLH.RQ_DATE, 'dd.mm.yyyy hh24:mi:ss') || '" (RN: ' || TO_CHAR(RDSCMMLH.RN) || + ', пользователь: ' || RDSCMMLH.RQ_AUTHID || ').'; + /* Изменим заголовок графика */ + update EQTCHSRV T + set T.DATEPRD_BEG = DDATEPRD_BEG, + T.DATEPRD_END = DDATEPRD_END, + T.NOTE = SNOTE + where T.RN = REQTCHSRV.RN; + /* Сдвинем работы */ + P_EQTCHSRV_MOVE_WORK(NCOMPANY => REQTCHSRV.COMPANY, + NRN => REQTCHSRV.RN, + NDUP_RN => null, + DDATEPRD_BEG => DDATEPRD_BEG, + DOLD_DATEPRD_BEG => REQTCHSRV.DATEPRD_BEG, + DDATEPRD_END => DDATEPRD_END, + NPERIOD => null, + NMODE => 1); + end EQCONFIG_THOBJ_CHNG_EQTCHSRV; + /* Формирование ремонтной ведомости для технического объекта */ procedure EQCONFIG_THOBJ_MAKE_EQRPSHEET ( diff --git a/panels/eqs_tech_cond_forecast/eqs_tech_cond_forecast_layout.js b/panels/eqs_tech_cond_forecast/eqs_tech_cond_forecast_layout.js index 3880842..f0a9751 100644 --- a/panels/eqs_tech_cond_forecast/eqs_tech_cond_forecast_layout.js +++ b/panels/eqs_tech_cond_forecast/eqs_tech_cond_forecast_layout.js @@ -240,7 +240,7 @@ const IUDFormTextField = ({ elementCode, elementValue, labelText, onChange, dict //Контроль свойств - Поле ввода формы IUDFormTextField.propTypes = { elementCode: PropTypes.string.isRequired, - elementValue: PropTypes.string, + elementValue: PropTypes.oneOfType([PropTypes.number, PropTypes.string, PropTypes.instanceOf(Date)]), labelText: PropTypes.string.isRequired, onChange: PropTypes.func, dictionary: PropTypes.func, diff --git a/panels/eqs_tech_cond_forecast/forecast_tab.js b/panels/eqs_tech_cond_forecast/forecast_tab.js index f99885f..6d08e6c 100644 --- a/panels/eqs_tech_cond_forecast/forecast_tab.js +++ b/panels/eqs_tech_cond_forecast/forecast_tab.js @@ -21,6 +21,7 @@ import { TechObjCard, eqConfigTechObjTableValueFormatter, eqConfigTechObjTableDataCellRender, + TechObjChangeEqTchSrv, TechObjMakeEqRpSheet, TechObjMakeDataSet } from "./forecast_tab_layout"; //Вспомогательные компоненты и вёрстка @@ -40,15 +41,16 @@ import { //Начальное состояние флагов обновления const REFRESH_INITIAL = { techObjSpec: 0, + techObjCard: 0, techObjForecastHistList: 0 }; //Начальное состояние диалогов -const DIALOGS_INITIAL = { makeEqRpSheet: false, makeEqDataSet: false, techObjCard: false }; +const DIALOGS_INITIAL = { makeEqRpSheet: false, makeEqDataSet: false, techObjCard: false, changeEqTchSrv: false }; //Начальное состояние спецификации технических объектов const TECH_OBJ_SPEC_INITIAL = { - parent: null, + parent: 8938140, filters: [], orders: [], pageNumber: 1 @@ -120,7 +122,7 @@ const ForecastTab = ({ onGoToAdmin }) => { ); //Загрузчик карточки выбранного технического объекта - const { techObjCard, techObjCardIsLoading } = useEqConfigTechObjCard(techObj.id); + const { techObjCard } = useEqConfigTechObjCard(techObj.id, refresh.techObjCard); //Загрузчик моделей выбранного технического объекта const { techObjModelsList } = useTechObjModelsList(techObj.id); @@ -173,9 +175,15 @@ const ForecastTab = ({ onGoToAdmin }) => { setTechObj(TECH_OBJ_INITIAL); }; + //При нажатии на "Изменить график ТО" в карточке технического объекта + const handleTechObjeCardChangeEqTchSrv = () => setDialogs(pv => ({ ...pv, changeEqTchSrv: true })); + //При нажатии на "Ремонтировать" в карточке технического объекта const handleTechObjeCardMakeEqRpSheet = () => setDialogs(pv => ({ ...pv, makeEqRpSheet: true })); + //При необходимости обновления карточки технического объекта + const handleCardDataRefresh = () => setRefresh(pv => ({ ...pv, techObjCard: pv.techObjCard + 1 })); + //При нажатии "ОК" в диалоге формирования ремонтной ведомости const handleTechObjMakeEqRpSheetOk = async values => { const data = await executeStored({ @@ -194,6 +202,29 @@ const ForecastTab = ({ onGoToAdmin }) => { //При нажитии "Отмена" в диалоге формирования ремонтной ведомости const handleTechObjMakeEqRpSheetCancel = () => setDialogs(pv => ({ ...pv, makeEqRpSheet: false })); + //При нажатии "ОК" в диалоге корректировки графика ТО и ремонтов + const handleTechObjChangeEqTchSrvOk = async values => { + await executeStored({ + stored: "UDO_PKG_EQUIPTCF.EQCONFIG_THOBJ_CHNG_EQTCHSRV", + args: { + NEQCONFIG: techObj.id, + NEQTCHSRV: values.eQTchSrv, + DPLANDATE_FROM: new Date(values.planDateFrom) + } + }); + handleCardDataRefresh(); + setDialogs(pv => ({ ...pv, changeEqTchSrv: false })); + const data = await executeStored({ stored: "UDO_PKG_EQUIPTCF.EQCONFIG_THOBJ_SELECT_EQTCHSRV", args: { NEQTCHSRV: values.eQTchSrv } }); + if (data.NIDENT) + pOnlineShowUnit({ + unitCode: "EquipTechServices", + inputParameters: [{ name: "in_SelectList_Ident", value: data.NIDENT }] + }); + }; + + //При нажитии "Отмена" в диалоге корректировки графика ТО и ремонтов + const handleTechObjChangeEqTchSrvCancel = () => setDialogs(pv => ({ ...pv, changeEqTchSrv: false })); + //При нажатии "ОК" в диалоге формирования выборки данных const handleTechObjMakeDataSetOk = async values => { const data = await executeStored({ @@ -234,7 +265,7 @@ const ForecastTab = ({ onGoToAdmin }) => { return (