create or replace package PKG_P8PANELS_SAMPLES as /* Получение списка контрагентов */ procedure AGNLIST_GET ( COUT out clob -- Список контрагентов ); /* Добавление контрагента */ procedure AGNLIST_INSERT ( SAGNABBR in varchar2, -- Мнемокод SAGNNAME in varchar2, -- Наименование NRN out number -- Рег. номер добавленного ); /* Удаление контрагента */ procedure AGNLIST_DELETE ( NRN in number -- Рег. номер удаляемого ); /* Таблица данных */ procedure DATA_GRID ( NPAGE_NUMBER in number, -- Номер страницы (игнорируется при NPAGE_SIZE=0) NPAGE_SIZE in number, -- Количество записей на странице (0 - все) CFILTERS in clob, -- Фильтры CORDERS in clob, -- Сортировки NINCLUDE_DEF in number, -- Признак включения описания колонок таблицы в ответ COUT out clob -- Сериализованная таблица данных ); /* График */ procedure CHART ( COUT out clob -- Сериализованный график ); /* Инициализация буфера данных для диаграмма Ганта */ procedure GANTT_INIT ( NIDENT in out number -- Идентификатор буфера сформированных данных (null - сгенерировать новый, !null - удалить старые данные и пересоздать с указанным идентификатором) ); /* Сбор данных для отображения диаграммы Ганта */ procedure GANTT ( NIDENT in number, -- Идентификатор процесса COUT out clob -- Сериализованные данные для диаграммы Ганта ); /* Исправление задачи в диаграмме Ганта */ procedure GANTT_MODIFY ( NIDENT in number, -- Идентификатор буфера NRN in number, -- Рег. номер записи DDATE_FROM in date, -- Дата начала задачи DDATE_TO in date -- Дата окончания задачи ); /* Инициализация буфера данных для диаграммы Ганта */ procedure CYCLOGRAM_INIT ( NIDENT in out number -- Идентификатор буфера сформированных данных (null - сгенерировать новый, !null - удалить старые данные и пересоздать с указанным идентификатором) ); /* Сбор данных для отображения циклограммы */ procedure CYCLOGRAM ( NIDENT in number, -- Идентификатор процесса COUT out clob -- Сериализованные данные для циклограммы ); /* Изменение задачи циклограммы */ procedure CYCLOGRAM_TASK_MODIFY ( NIDENT in number, -- Идентификатор буфера NRN in number, -- Рег. номер записи SDATE_FROM in varchar2, -- Дата начала (в строковом представлении) SDATE_TO in varchar2 -- Дата окончания (в строковом представлении) ); end PKG_P8PANELS_SAMPLES; / create or replace package body PKG_P8PANELS_SAMPLES as /* Константы - циклограмма */ NCG_MULTIPLIER constant PKG_STD.TNUMBER := 5; -- Множитель для ширины отображения /* Получение списка контрагентов */ procedure AGNLIST_GET ( COUT out clob -- Список контрагентов ) is NVERSION PKG_STD.TREF; -- Рег. номер версии словаря контрагентов begin NVERSION := GET_SESSION_VERSION(SUNITCODE => 'AGNLIST'); PKG_XFAST.PROLOGUE(ITYPE => PKG_XFAST.CONTENT_); PKG_XFAST.DOWN_NODE(SNAME => 'DATA'); for C in (select TMP.* from (select D.*, ROWNUM NROWNUM from (select T.RN NRN, T.AGNABBR SAGNABBR, T.AGNNAME SAGNNAME from AGNLIST T where T.VERSION = NVERSION and exists (select /*+ INDEX(UP I_USERPRIV_CATALOG_ROLEID) */ null from USERPRIV UP where UP.CATALOG = T.CRN and UP.ROLEID in (select /*+ INDEX(UR I_USERROLES_AUTHID_FK) */ UR.ROLEID from USERROLES UR where UR.AUTHID = UTILIZER) union all select /*+ INDEX(UP I_USERPRIV_CATALOG_AUTHID) */ null from USERPRIV UP where UP.CATALOG = T.CRN and UP.AUTHID = UTILIZER) order by T.RN desc) D) TMP where TMP.NROWNUM <= 10) loop PKG_XFAST.DOWN_NODE(SNAME => 'AGENTS'); PKG_XFAST.ATTR(SNAME => 'NRN', NVALUE => C.NRN); PKG_XFAST.ATTR(SNAME => 'SAGNABBR', SVALUE => C.SAGNABBR); PKG_XFAST.ATTR(SNAME => 'SAGNNAME', SVALUE => C.SAGNNAME); PKG_XFAST.UP(); end loop; PKG_XFAST.UP(); COUT := PKG_XFAST.SERIALIZE_TO_CLOB(); PKG_XFAST.EPILOGUE(); end AGNLIST_GET; /* Добавление контрагента */ procedure AGNLIST_INSERT ( SAGNABBR in varchar2, -- Мнемокод SAGNNAME in varchar2, -- Наименование NRN out number -- Рег. номер добавленного ) is NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Текущая организация NCRN PKG_STD.TREF; -- Каталог размещения контрагента begin if (SAGNABBR is null) then P_EXCEPTION(0, 'Не указан мнемокод.'); end if; if (SAGNABBR is null) then P_EXCEPTION(0, 'Не указано наименование.'); end if; FIND_ROOT_CATALOG(NCOMPANY => NCOMPANY, SCODE => 'AGNLIST', NCRN => NCRN); P_AGNLIST_INSERT(NCOMPANY => NCOMPANY, CRN => NCRN, AGNABBR => SAGNABBR, AGNTYPE => 0, AGNNAME => SAGNNAME, AGNIDNUMB => null, ECONCODE => null, ORGCODE => null, AGNFAMILYNAME => null, AGNFIRSTNAME => null, AGNLASTNAME => null, AGNFAMILYNAME_TO => null, AGNFIRSTNAME_TO => null, AGNLASTNAME_TO => null, AGNFAMILYNAME_FR => null, AGNFIRSTNAME_FR => null, AGNLASTNAME_FR => null, AGNFAMILYNAME_AC => null, AGNFIRSTNAME_AC => null, AGNLASTNAME_AC => null, AGNFAMILYNAME_ABL => null, AGNFIRSTNAME_ABL => null, AGNLASTNAME_ABL => null, EMP => 0, EMPPOST => null, EMPPOST_FROM => null, EMPPOST_TO => null, EMPPOST_AC => null, EMPPOST_ABL => null, AGNBURN => null, PHONE => null, PHONE2 => null, FAX => null, TELEX => null, MAIL => null, IMAGE => null, DDISCDATE => null, AGN_COMMENT => null, NSEX => 0, SPENSION_NBR => null, SMEDPOLICY_SER => null, SMEDPOLICY_NUMB => null, SPROPFORM => null, SREASON_CODE => null, NRESIDENT_SIGN => 0, STAXPSTATUS => null, SOGRN => null, SPRFMLSTS => null, SPRNATION => null, SCITIZENSHIP => null, ADDR_BURN => null, SPRMLREL => null, SOKATO => null, SPFR_NAME => null, DPFR_FILL_DATE => null, DPFR_REG_DATE => null, SPFR_REG_NUMB => null, SSFR_REG_NUMB => null, SFULLNAME => null, SOKFS => null, SOKOPF => null, STFOMS => null, SFSS_REG_NUMB => null, SFSS_SUBCODE => null, NCOEFFIC => 0, DAGNDEATH => null, NOLD_RN => null, SOKTMO => null, SINN_CITIZENSHIP => null, DTAX_REG_DATE => null, SORIGINAL_NAME => null, NIND_BUSINESSMAN => 0, SFNS_CODE => null, SCTZNSHP_TYPE => null, NCONTACT_METHOD => null, SMF_ID => null, SOKOGU => null, NJURPERS_SUBDIV => null, NRN => NRN); end AGNLIST_INSERT; /* Удаление контрагента */ procedure AGNLIST_DELETE ( NRN in number -- Рег. номер удаляемого ) is begin P_AGNLIST_DELETE(NCOMPANY => GET_SESSION_COMPANY(), RN => NRN); end AGNLIST_DELETE; /* Таблица данных */ procedure DATA_GRID ( NPAGE_NUMBER in number, -- Номер страницы (игнорируется при NPAGE_SIZE=0) NPAGE_SIZE in number, -- Количество записей на странице (0 - все) CFILTERS in clob, -- Фильтры CORDERS in clob, -- Сортировки NINCLUDE_DEF in number, -- Признак включения описания колонок таблицы в ответ COUT out clob -- Сериализованная таблица данных ) is NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса NIDENT PKG_STD.TREF := GEN_IDENT(); -- Идентификатор отбора RF PKG_P8PANELS_VISUAL.TDG_FILTERS; -- Фильтры RO PKG_P8PANELS_VISUAL.TDG_ORDERS; -- Сортировки RDG PKG_P8PANELS_VISUAL.TDG; -- Описание таблицы RAGN_TYPES PKG_P8PANELS_VISUAL.TDG_COL_VALS; -- Предопределенные значения "Типа контрагентов" RDG_ROW PKG_P8PANELS_VISUAL.TDG_ROW; -- Строка таблицы NROW_FROM PKG_STD.TREF; -- Номер строки с NROW_TO PKG_STD.TREF; -- Номер строки по CSQL clob; -- Буфер для запроса ICURSOR integer; -- Курсор для исполнения запроса SGROUP PKG_STD.TSTRING; -- Буфер для группы SAGNINFO PKG_STD.TSTRING; -- Буфер для "Сведений" SAGNNAME PKG_STD.TSTRING; -- Буфер для "Наименования" NAGNTYPE PKG_STD.TREF; -- Буфер для "Типа" begin /* Читаем фильтры */ RF := PKG_P8PANELS_VISUAL.TDG_FILTERS_FROM_XML(CFILTERS => CFILTERS); /* Читем сортировки */ RO := PKG_P8PANELS_VISUAL.TDG_ORDERS_FROM_XML(CORDERS => CORDERS); /* Преобразуем номер и размер страницы в номер строк с и по */ PKG_P8PANELS_VISUAL.UTL_ROWS_LIMITS_CALC(NPAGE_NUMBER => NPAGE_NUMBER, NPAGE_SIZE => NPAGE_SIZE, NROW_FROM => NROW_FROM, NROW_TO => NROW_TO); /* Инициализируем таблицу данных */ RDG := PKG_P8PANELS_VISUAL.TDG_MAKE(BFIXED_HEADER => true, NFIXED_COLUMNS => 2); /* Описываем колонки таблицы данных */ PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SAGNABBR', SCAPTION => 'Мнемокод', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, SCOND_FROM => 'AgentAbbr', BVISIBLE => true, BORDER => true, BFILTER => true, NWIDTH => 150); PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SAGNINFO', SCAPTION => 'Сведения', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, BVISIBLE => true, BORDER => false, BFILTER => false, BEXPANDABLE => true, NWIDTH => 300); PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SAGNNAME', SCAPTION => 'Наименование', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, SCOND_FROM => 'AgentName', BVISIBLE => true, BORDER => true, BFILTER => true, SPARENT => 'SAGNINFO', NWIDTH => 200); PKG_P8PANELS_VISUAL.TDG_COL_VALS_ADD(RCOL_VALS => RAGN_TYPES, NVALUE => 0); PKG_P8PANELS_VISUAL.TDG_COL_VALS_ADD(RCOL_VALS => RAGN_TYPES, NVALUE => 1); PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NAGNTYPE', SCAPTION => 'Тип', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, SCOND_FROM => 'AgentType', BVISIBLE => true, BORDER => true, BFILTER => true, SPARENT => 'SAGNINFO', NWIDTH => 100, RCOL_VALS => RAGN_TYPES, SHINT => 'В Системе бывают контрагенты двух типов:
' || 'Юридическое лицо - организация, которая имеет в собственности, хозяйственном ведении ' || 'или оперативном управлении обособленное имущество, отвечает по своим обязательствам этим имуществом, может от своего ' || 'имени приобретать и осуществлять имущественные и личные неимущественные права, отвечать по своим обязанностям.
' || 'Физическое лицо - субъект правовых отношений, представляющий собой одного человека.'); PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SFULLNAME', SCAPTION => 'Полное наименование', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR); PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SAGNIDNUMB', SCAPTION => 'ИНН', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR); /* Обходим данные */ begin /* Добавляем подсказку совместимости */ CSQL := PKG_SQL_BUILD.COMPATIBLE(SSQL => CSQL); /* Формируем запрос */ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => 'select *'); PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from (select D.*,'); PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.SQLROWNUM() || ' NROW'); PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from (select AG.AGNABBR SAGNABBR,'); PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' AG.AGNNAME SAGNNAME,'); PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' AG.AGNTYPE NAGNTYPE,'); PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' AG.FULLNAME SFULLNAME,'); PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' AG.AGNIDNUMB SAGNIDNUMB'); PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from AGNLIST AG'); PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' where exists (select ' || PKG_SQL_BUILD.SET_HINT(SHINT => 'INDEX(UP I_USERPRIV_CATALOG_ROLEID)') || ' null'); PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from USERPRIV UP'); PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' where UP."CATALOG" = AG.CRN'); PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and UP.ROLEID in (select ' || PKG_SQL_BUILD.SET_HINT(SHINT => 'INDEX(UR I_USERROLES_AUTHID_FK)') || ' UR.ROLEID'); PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from USERROLES UR where UR.AUTHID = UTILIZER())'); PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' union all'); PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' select ' || PKG_SQL_BUILD.SET_HINT(SHINT => 'INDEX(UP I_USERPRIV_CATALOG_AUTHID)') || ' null'); PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from USERPRIV UP where UP."CATALOG" = AG.CRN and UP.AUTHID = UTILIZER())'); PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and AG.RN in (select ID from COND_BROKER_IDSMART where IDENT = :NIDENT) %ORDER_BY%) D) F'); PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' where F.NROW between :NROW_FROM and :NROW_TO'); /* Учтём сортировки */ PKG_P8PANELS_VISUAL.TDG_ORDERS_SET_QUERY(RDATA_GRID => RDG, RORDERS => RO, SPATTERN => '%ORDER_BY%', CSQL => CSQL); /* Учтём фильтры */ PKG_P8PANELS_VISUAL.TDG_FILTERS_SET_QUERY(NIDENT => NIDENT, NCOMPANY => NCOMPANY, SUNIT => 'AGNLIST', SPROCEDURE => 'P_AGNLIST_BASE_COND', RDATA_GRID => RDG, RFILTERS => RF); /* Разбираем его */ ICURSOR := PKG_SQL_DML.OPEN_CURSOR(SWHAT => 'SELECT'); PKG_SQL_DML.PARSE(ICURSOR => ICURSOR, SQUERY => CSQL); /* Делаем подстановку параметров */ PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NIDENT', NVALUE => NIDENT); PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NROW_FROM', NVALUE => NROW_FROM); PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NROW_TO', NVALUE => NROW_TO); /* Описываем структуру записи курсора */ PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 1); PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 2); PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 3); PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 4); PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 5); PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 6); /* Делаем выборку */ if (PKG_SQL_DML.EXECUTE(ICURSOR => ICURSOR) = 0) then null; end if; /* Обходим выбранные записи */ while (PKG_SQL_DML.FETCH_ROWS(ICURSOR => ICURSOR) > 0) loop /* Добавляем колонки с данными */ PKG_SQL_DML.COLUMN_VALUE_STR(ICURSOR => ICURSOR, IPOSITION => 2, SVALUE => SAGNNAME); PKG_SQL_DML.COLUMN_VALUE_NUM(ICURSOR => ICURSOR, IPOSITION => 3, NVALUE => NAGNTYPE); if (NAGNTYPE = 0) then SGROUP := 'JUR'; SAGNINFO := SAGNNAME || ', ЮЛ'; PKG_P8PANELS_VISUAL.TDG_ADD_GROUP(RDATA_GRID => RDG, SNAME => SGROUP, SCAPTION => 'Юридические лица', BEXPANDABLE => true, BEXPANDED => false); else SGROUP := 'PERS'; SAGNINFO := SAGNNAME || ', ФЛ'; PKG_P8PANELS_VISUAL.TDG_ADD_GROUP(RDATA_GRID => RDG, SNAME => SGROUP, SCAPTION => 'Физические лица', BEXPANDABLE => true, BEXPANDED => false); end if; RDG_ROW := PKG_P8PANELS_VISUAL.TDG_ROW_MAKE(SGROUP => SGROUP); PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SAGNABBR', ICURSOR => ICURSOR, NPOSITION => 1); PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SAGNINFO', SVALUE => SAGNINFO); PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SAGNNAME', SVALUE => SAGNNAME); PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NAGNTYPE', NVALUE => NAGNTYPE); PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SFULLNAME', ICURSOR => ICURSOR, NPOSITION => 4); PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SAGNIDNUMB', ICURSOR => ICURSOR, NPOSITION => 5); /* Добавляем строку в таблицу */ PKG_P8PANELS_VISUAL.TDG_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW); end loop; /* Освобождаем курсор */ PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR); exception when others then PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR); raise; end; /* Сериализуем описание */ COUT := PKG_P8PANELS_VISUAL.TDG_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => NINCLUDE_DEF); end DATA_GRID; /* График */ procedure CHART ( COUT out clob -- Сериализованный график ) is NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса RCH PKG_P8PANELS_VISUAL.TCHART; -- График RCH_DS PKG_P8PANELS_VISUAL.TCHART_DATASET; -- Набор данных RATTR_VALS PKG_P8PANELS_VISUAL.TCHART_DATASET_ITEM_ATTR_VALS; -- Атрибуты элемента набора данных begin /* Сформируем заголовок графика */ RCH := PKG_P8PANELS_VISUAL.TCHART_MAKE(STYPE => PKG_P8PANELS_VISUAL.SCHART_TYPE_BAR, STITLE => 'Топ 5 контрагентов по сумме договоров', SLGND_POS => PKG_P8PANELS_VISUAL.SCHART_LGND_POS_RIGHT); /* Сформируем набор данных */ RCH_DS := PKG_P8PANELS_VISUAL.TCHART_DATASET_MAKE(SCAPTION => 'Сумма договоров'); /* Обходим договоры, сгруппированные по контрагентам */ for C in (select D.SAGENT, D.NSUM from (select AG.AGNABBR SAGENT, sum(CN.DOC_SUMTAX * (CN.CURBASE / CN.CURCOURS)) NSUM from CONTRACTS CN, AGNLIST AG where CN.COMPANY = NCOMPANY and CN.AGENT = AG.RN group by AG.AGNABBR order by 2 desc) D where ROWNUM <= 5) loop /* Добавим метку для контрагента */ PKG_P8PANELS_VISUAL.TCHART_ADD_LABEL(RCHART => RCH, SLABEL => C.SAGENT); /* Сформируем дополнительные атрибуты для клиентского приложения - будем использовать их при открытии раздела "Договоры" для отбора */ PKG_P8PANELS_VISUAL.TCHART_DATASET_ITM_ATTR_VL_ADD(RATTR_VALS => RATTR_VALS, SNAME => 'SCOND', SVALUE => 'in_SAGENT', BCLEAR => true); PKG_P8PANELS_VISUAL.TCHART_DATASET_ITM_ATTR_VL_ADD(RATTR_VALS => RATTR_VALS, SNAME => 'SCOND_VALUE', SVALUE => C.SAGENT); /* Добавим контрагента в набор данных */ PKG_P8PANELS_VISUAL.TCHART_DATASET_ADD_ITEM(RDATASET => RCH_DS, NVALUE => C.NSUM, RATTR_VALS => RATTR_VALS); 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 CHART; /* Очистка буфера данных для диаграммы Ганта */ procedure GANTT_BASE_CLEAN ( NIDENT in number -- Идентификатор буфера ) is begin /* Удалим из буфера всё с указанным идентификатором */ delete from P8PNL_SMPL_GANTT T where T.IDENT = NIDENT; end GANTT_BASE_CLEAN; /* Добавление данных в буфер диаграммы Ганта */ procedure GANTT_BASE_INSERT ( NIDENT in number, -- Идентификатор буфера NTYPE in number, -- Тип задачи (0 - этап/веха, 1 - работа) SNUMB in varchar2, -- Номер задачи SNAME in varchar2, -- Наименование задачи DDATE_FROM in date, -- Дата начала задачи DDATE_TO in date, -- Дата окончания задачи NSTATE in number -- Состояние (0 - не выполняется, 1 - выполняется) ) is begin /* Добавим запись */ insert into P8PNL_SMPL_GANTT (RN, IDENT, type, NUMB, name, DATE_FROM, DATE_TO, STATE) values (GEN_ID(), NIDENT, NTYPE, SNUMB, SNAME, DDATE_FROM, DDATE_TO, NSTATE); end GANTT_BASE_INSERT; /* Исправление данных в буфере диаграммы Ганта */ procedure GANTT_BASE_UPDATE ( NIDENT in number, -- Идентификатор буфера NRN in number, -- Рег. номер записи NTYPE in number, -- Тип задачи (0 - этап/веха, 1 - работа) SNUMB in varchar2, -- Номер задачи SNAME in varchar2, -- Наименование задачи DDATE_FROM in date, -- Дата начала задачи DDATE_TO in date -- Дата окончания задачи ) is begin /* Изменим запись */ update P8PNL_SMPL_GANTT T set T.TYPE = NTYPE, T.NUMB = SNUMB, T.NAME = SNAME, T.DATE_FROM = DDATE_FROM, T.DATE_TO = DDATE_TO where T.RN = NRN and T.IDENT = NIDENT; end GANTT_BASE_UPDATE; /* Инициализация буфера данных для диаграммы Ганта */ procedure GANTT_INIT ( NIDENT in out number -- Идентификатор буфера сформированных данных (null - сгенерировать новый, !null - удалить старые данные и пересоздать с указанным идентификатором) ) is /* Константы */ NSTAGE_LEN constant PKG_STD.TNUMBER := 3; -- Длительность этапа (в месяцах) /* Переменные */ NYEAR PKG_STD.TNUMBER; -- Текущий год NMONTH PKG_STD.TNUMBER; -- Месяц начала этапа DDATE_FROM PKG_STD.TLDATE; -- Дата начала этапа DDATE_TO PKG_STD.TLDATE; -- Дата окончания этапа DDATE_FROM_J PKG_STD.TLDATE; -- Дата начала работы DDATE_TO_J PKG_STD.TLDATE; -- Дата окончания работы NSTATE PKG_STD.TNUMBER; -- Состояние задачи begin /* Удаляем старые данные из буфера */ if (NIDENT is not null) then GANTT_BASE_CLEAN(NIDENT => NIDENT); else /* Илиформируем новый идентификатор, если не задан */ NIDENT := GEN_IDENT(); end if; /* Фиксируем текущий год */ NYEAR := EXTRACT(year from sysdate); /* Этапы */ for ST in 1 .. 12 / NSTAGE_LEN loop /* Сформируем период этапа */ NMONTH := ST * NSTAGE_LEN - NSTAGE_LEN + 1; DDATE_FROM := TO_DATE('01.' || NMONTH || '.' || TO_CHAR(NYEAR), 'dd.mm.yyyy'); DDATE_TO := LAST_DAY(ADD_MONTHS(DDATE_FROM, NSTAGE_LEN) - 1); /* Сформируем значение для атриуба "состояние" этапа */ if (TRUNC(sysdate) between TRUNC(DDATE_FROM) and TRUNC(DDATE_TO)) then NSTATE := 1; else NSTATE := 0; end if; /* Добавим его в буфер */ GANTT_BASE_INSERT(NIDENT => NIDENT, NTYPE => 0, SNUMB => TO_CHAR(ST), SNAME => 'Этап ' || TO_CHAR(ST), DDATE_FROM => DDATE_FROM, DDATE_TO => DDATE_TO, NSTATE => NSTATE); /* Работы */ for J in 0 .. NSTAGE_LEN - 1 loop /* Сформируем период работы */ DDATE_FROM_J := ADD_MONTHS(DDATE_FROM, J); DDATE_TO_J := LAST_DAY(ADD_MONTHS(DDATE_FROM, J + 1) - 1); /* Сформируем значение для атриуба "состояние" работы */ if (TRUNC(sysdate) between TRUNC(DDATE_FROM_J) and TRUNC(DDATE_TO_J)) then NSTATE := 1; else NSTATE := 0; end if; /* Добавим в буфер */ GANTT_BASE_INSERT(NIDENT => NIDENT, NTYPE => 1, SNUMB => TO_CHAR(ST) || '.' || TO_CHAR(J + 1), SNAME => 'Работа ' || TO_CHAR(J + 1) || ' этапа ' || TO_CHAR(ST), DDATE_FROM => DDATE_FROM_J, DDATE_TO => DDATE_TO_J, NSTATE => NSTATE); end loop; end loop; end GANTT_INIT; /* Сбор данных для отображения диаграммы Ганта */ procedure GANTT ( NIDENT in number, -- Идентификатор процесса COUT out clob -- Сериализованные данные для диаграммы Ганта ) is /* Константы */ SBG_COLOR_STAGE constant PKG_STD.TSTRING := 'cadetblue'; -- Цвет заливки этапов SBG_COLOR_JOB constant PKG_STD.TSTRING := 'lightgreen'; -- Цвет заливки работ /* Переменные */ RG PKG_P8PANELS_VISUAL.TGANTT; -- Описание диаграммы Ганта RGT PKG_P8PANELS_VISUAL.TGANTT_TASK; -- Описание задачи для диаграммы STASK_BG_COLOR PKG_STD.TSTRING; -- Цвет фона задачи begin /* Инициализируем диаграмму Ганта */ RG := PKG_P8PANELS_VISUAL.TGANTT_MAKE(STITLE => 'Задачи на ' || TO_CHAR(EXTRACT(year from sysdate)) || ' год', NZOOM => PKG_P8PANELS_VISUAL.NGANTT_ZOOM_MONTH); /* Добавим динамические атрибуты к задачам */ PKG_P8PANELS_VISUAL.TGANTT_ADD_TASK_ATTR(RGANTT => RG, SNAME => 'type', SCAPTION => 'Тип', BVISIBLE => true); PKG_P8PANELS_VISUAL.TGANTT_ADD_TASK_ATTR(RGANTT => RG, SNAME => 'state', SCAPTION => 'Состояние', BVISIBLE => false); /* Добавим описание цветов задач */ PKG_P8PANELS_VISUAL.TGANTT_ADD_TASK_COLOR(RGANTT => RG, SBG_COLOR => SBG_COLOR_JOB, SDESC => 'Этот цвет для задач.'); PKG_P8PANELS_VISUAL.TGANTT_ADD_TASK_COLOR(RGANTT => RG, SBG_COLOR => SBG_COLOR_STAGE, SDESC => 'Этим цветом выделены этапы.'); /* Обходим буфер */ for C in (select T.* from P8PNL_SMPL_GANTT T where T.IDENT = NIDENT order by T.RN) loop /* Определимся с форматированием */ if (C.TYPE = 0) then STASK_BG_COLOR := SBG_COLOR_STAGE; else STASK_BG_COLOR := SBG_COLOR_JOB; end if; /* Сформируем задачу */ RGT := PKG_P8PANELS_VISUAL.TGANTT_TASK_MAKE(NRN => C.RN, SNUMB => C.NUMB, SCAPTION => C.NUMB || ' - ' || C.NAME, SNAME => C.NAME, DSTART => C.DATE_FROM, DEND => C.DATE_TO, SBG_COLOR => STASK_BG_COLOR); PKG_P8PANELS_VISUAL.TGANTT_TASK_ADD_ATTR_VAL(RGANTT => RG, RTASK => RGT, SNAME => 'type', SVALUE => C.TYPE, BCLEAR => true); PKG_P8PANELS_VISUAL.TGANTT_TASK_ADD_ATTR_VAL(RGANTT => RG, RTASK => RGT, SNAME => 'state', SVALUE => C.STATE); /* Добавляем задачу в диаграмму */ PKG_P8PANELS_VISUAL.TGANTT_ADD_TASK(RGANTT => RG, RTASK => RGT); end loop; /* Сериализуем собранные данные */ COUT := PKG_P8PANELS_VISUAL.TGANTT_TO_XML(RGANTT => RG); end GANTT; /* Исправление задачи в диаграмме Ганта */ procedure GANTT_MODIFY ( NIDENT in number, -- Идентификатор буфера NRN in number, -- Рег. номер записи DDATE_FROM in date, -- Дата начала задачи DDATE_TO in date -- Дата окончания задачи ) is begin for C in (select T.* from P8PNL_SMPL_GANTT T where T.RN = NRN and T.IDENT = NIDENT) loop GANTT_BASE_UPDATE(NIDENT => C.IDENT, NRN => C.RN, NTYPE => C.TYPE, SNUMB => C.NUMB, SNAME => C.NAME, DDATE_FROM => TRUNC(DDATE_FROM), DDATE_TO => TRUNC(DDATE_TO)); end loop; end GANTT_MODIFY; /* Очистка буфера данных для циклограммы */ procedure CYCLOGRAM_BASE_CLEAN ( NIDENT in number -- Идентификатор буфера ) is begin /* Удалим из буфера всё с указанным идентификатором */ delete from P8PNL_SMPL_CYCLOGRAM T where T.IDENT = NIDENT; end CYCLOGRAM_BASE_CLEAN; /* Добавление данных в буфер циклограммы */ procedure CYCLOGRAM_BASE_INSERT ( NIDENT in number, -- Идентификатор буфера NTYPE in number, -- Тип (0 - колонка, 1 - группа, 2 - задача) SNAME in varchar2, -- Наименование NPOS_START in number := null, -- Позиция начала элемента NPOS_END in number := null, -- Позиция окончания элемента DDATE_FROM in date := null, -- Дата начала DDATE_TO in date := null, -- Дата окончания NTASK_GROUP in number := null, -- Рег. номер группы NRN out number -- Рег. номер записи ) is begin /* Генерируем рег. номер записи */ NRN := GEN_ID(); /* Добавим запись */ insert into P8PNL_SMPL_CYCLOGRAM (RN, IDENT, type, name, POS_START, POS_END, DATE_FROM, DATE_TO, TASK_GROUP) values (NRN, NIDENT, NTYPE, SNAME, NPOS_START, NPOS_END, DDATE_FROM, DDATE_TO, NTASK_GROUP); end CYCLOGRAM_BASE_INSERT; /* Исправление данных в буфере циклограммы */ procedure CYCLOGRAM_BASE_UPDATE ( NIDENT in number, -- Идентификатор буфера NRN in number, -- Рег. номер записи NTYPE in number, -- Тип задачи (0 - этап/веха, 1 - работа) SNAME in varchar2, -- Наименование NPOS_START in number, -- Позиция начала NPOS_END in number, -- Позиция окончания DDATE_FROM in date, -- Дата начала DDATE_TO in date, -- Дата окончания NTASK_GROUP in number -- Рег. номер группы ) is begin /* Изменим запись */ update P8PNL_SMPL_CYCLOGRAM T set T.TYPE = NTYPE, T.NAME = SNAME, T.POS_START = NPOS_START, T.POS_END = NPOS_END, T.DATE_FROM = DDATE_FROM, T.DATE_TO = DDATE_TO, T.TASK_GROUP = NTASK_GROUP where T.RN = NRN and T.IDENT = NIDENT; end CYCLOGRAM_BASE_UPDATE; /* Инициализация буфера данных для циклограммы */ procedure CYCLOGRAM_INIT ( NIDENT in out number -- Идентификатор буфера сформированных данных (null - сгенерировать новый, !null - удалить старые данные и пересоздать с указанным идентификатором) ) is NYEAR PKG_STD.TNUMBER; -- Текущий год DCYCLOGRAM_START PKG_STD.TLDATE; -- Дата начала циклограммы DMONTH_CUR PKG_STD.TLDATE; -- Текущий месяц (для расчетов) DMONTH_START PKG_STD.TLDATE; -- Начало месяца (для расчетов) DMONTH_END PKG_STD.TLDATE; -- Окончание месяца (для расчетов) NMONTH_DAYS PKG_STD.TNUMBER; -- Количество дней месяца NSTART PKG_STD.TNUMBER := 0; -- Позиция начала элемента NEND PKG_STD.TNUMBER := 0; -- Позиция окончания элемента NGROUP PKG_STD.TNUMBER; -- Рег. номер группы NDUMMY PKG_STD.TNUMBER; -- Буфер для рег. номера NMONTH PKG_STD.TNUMBER; -- Месяц даты /* Инициализация группы */ procedure INIT_GROUP ( NIDENT in number, -- Идентификатор буфера DDATE in date, -- Текущая обрабатываемая дата NRN in out number -- Рег. номер группы ) is NMONTH PKG_STD.TNUMBER; -- Месяц даты begin /* Считываем текущий месяц */ NMONTH := D_MONTH(DDATE => DDATE); /* Исходим от даты (формируем группу на начало каждого квартала) */ case NMONTH /* Первый квартал */ when 1 then /* Добавляем группу */ CYCLOGRAM_BASE_INSERT(NIDENT => NIDENT, NTYPE => 1, SNAME => 'I группа', NRN => NRN); /* Второй квартал */ when 4 then /* Добавляем группу */ CYCLOGRAM_BASE_INSERT(NIDENT => NIDENT, NTYPE => 1, SNAME => 'II группа', NRN => NRN); /* Третий квартал */ when 7 then /* Добавляем группу */ CYCLOGRAM_BASE_INSERT(NIDENT => NIDENT, NTYPE => 1, SNAME => 'III группа', NRN => NRN); /* Четвертый квартал */ when 10 then /* ДОбавляем группу */ CYCLOGRAM_BASE_INSERT(NIDENT => NIDENT, NTYPE => 1, SNAME => 'IV группа', NRN => NRN); else null; end case; end INIT_GROUP; begin /* Удаляем старые данные из буфера */ if (NIDENT is not null) then CYCLOGRAM_BASE_CLEAN(NIDENT => NIDENT); else /* Илиформируем новый идентификатор, если не задан */ NIDENT := GEN_IDENT(); end if; /* Фиксируем текущий год */ NYEAR := EXTRACT(year from sysdate); /* Фиксируем дату начала циклограммы */ DCYCLOGRAM_START := TO_DATE('01.01.' || NYEAR, 'dd.mm.yyyy'); /* Добавляем колонки и групповые задачи (месяцы года) */ for I in 0 .. 11 loop /* Рассчитываем текущий месяц */ DMONTH_CUR := ADD_MONTHS(DCYCLOGRAM_START, I); /* Считываем первый и последний день месяца */ P_FIRST_LAST_DAY(DCALCDATE => DMONTH_CUR, DBGNDATE => DMONTH_START, DENDDATE => DMONTH_END); /* Рассчитываем количество дней месяца */ NMONTH_DAYS := DMONTH_END - DMONTH_START + 1; /* Рассчитываем позицию окончания элемента */ NEND := NSTART + (NMONTH_DAYS * NCG_MULTIPLIER); /* Определяем номер месяца */ NMONTH := D_MONTH(DDATE => DMONTH_CUR); /* Добавляем колонку в таблицу */ CYCLOGRAM_BASE_INSERT(NIDENT => NIDENT, NTYPE => 0, SNAME => TO_CHAR(NMONTH), NPOS_START => NSTART, NPOS_END => NEND, NRN => NDUMMY); /* Инициализируем группу */ INIT_GROUP(NIDENT => NIDENT, DDATE => DMONTH_CUR, NRN => NGROUP); /* Добавляем задачу */ CYCLOGRAM_BASE_INSERT(NIDENT => NIDENT, NTYPE => 2, SNAME => 'Работа ' || TO_CHAR(I + 1), NPOS_START => NSTART, NPOS_END => NEND, DDATE_FROM => DMONTH_START, DDATE_TO => DMONTH_END, NTASK_GROUP => NGROUP, NRN => NDUMMY); /* Если это февраль, май, август или ноябрь - добавляем особосбленную задачу */ if (NMONTH in (2, 5, 8, 11)) then /* Добавляем обособленную задачу */ CYCLOGRAM_BASE_INSERT(NIDENT => NIDENT, NTYPE => 2, SNAME => 'Обособленная работа ' || NMONTH, NPOS_START => NSTART, NPOS_END => NEND, DDATE_FROM => DMONTH_START, DDATE_TO => DMONTH_END, NRN => NDUMMY); end if; /* Рассчитываем начало следующего месяца */ NSTART := NEND; end loop; end CYCLOGRAM_INIT; /* Сбор данных для отображения циклограммы */ procedure CYCLOGRAM ( NIDENT in number, -- Идентификатор процесса COUT out clob -- Сериализованные данные для циклограммы ) is CG PKG_P8PANELS_VISUAL.TCYCLOGRAM; -- Описание циклограммы RTASK PKG_P8PANELS_VISUAL.TCYCLOGRAM_TASK; -- Описание задачи циклограммы NLINE_NUMB PKG_STD.TNUMBER := 0; -- Номер строки NLINE_NUMB_TMP PKG_STD.TNUMBER := 0; -- Номер строки (буфер) DTASK_DATE_START PKG_STD.TLDATE; -- Дата начала этапа DTASK_DATE_END PKG_STD.TLDATE; -- Дата окончания этапа NTASK_START PKG_STD.TNUMBER := 0; -- Позиция начала этапа NTASK_END PKG_STD.TNUMBER := 0; -- Позиция окончания этапа STASK_NAME PKG_STD.TSTRING; -- Наименование задачи SCOLOR_WHITE PKG_STD.TSTRING := 'white'; -- Цвет - белый SBG_TASK_COLOR_W_GRP PKG_STD.TSTRING := '#6bc982'; -- Цвет задачи с группой SHL_TASK_COLOR_W_GRP PKG_STD.TSTRING := '#7dd592'; -- Цвет наведения задачи с группой SBG_TASK_COLOR_WO_GRP PKG_STD.TSTRING := '#e36d6d'; -- Цвет задачи без группы STEXT_COLOR_TASK_WO_GRP PKG_STD.TSTRING := '#e5e5e5'; -- Цвет текста задачи без группы SBG_TASK_COLOR_GRP PKG_STD.TSTRING := 'cadetblue'; -- Цвет групповой задачи SHL_TASK_COLOR_GRP PKG_STD.TSTRING := '#6fadaf'; -- Цвет наведения групповой задачи /* Считывание значений группирующей задачи */ procedure GROUP_TASK_GET ( NIDENT in number, -- Идентификатор процесса NGROUP in number := null, -- Рег. номер группы NFLAG_WO_GROUP in number := 0, -- Признак отбора задач без групп (0 - нет, 1 - да) DTASK_DATE_START out date, -- Дата начала этапа DTASK_DATE_END out date, -- Дата окончания этапа NTASK_START out number, -- Позиция начала этапа NTASK_END out number -- Позиция окончания этапа ) is begin /* Считываем начало и окончание этапа */ begin select min(T.DATE_FROM), max(T.DATE_TO), min(T.POS_START), max(T.POS_END) into DTASK_DATE_START, DTASK_DATE_END, NTASK_START, NTASK_END from P8PNL_SMPL_CYCLOGRAM T where T.IDENT = NIDENT and (((NFLAG_WO_GROUP = 1) and (T.TASK_GROUP is null)) or ((NFLAG_WO_GROUP = 0) and (T.TASK_GROUP is not null))) and ((NGROUP is null) or ((NGROUP is not null) and (T.TASK_GROUP = NGROUP))) and T.TYPE = 2; end; end GROUP_TASK_GET; begin /* Инициализируем циклограмму */ CG := PKG_P8PANELS_VISUAL.TCYCLOGRAM_MAKE(STITLE => 'Задачи на ' || TO_CHAR(EXTRACT(year from sysdate)) || ' год'); /* Добавляем атрибуты */ PKG_P8PANELS_VISUAL.TCYCLOGRAM_ADD_TASK_ATTR(RCYCLOGRAM => CG, SNAME => 'ddate_start', SCAPTION => 'Дата начала', BVISIBLE => true, BCLEAR => true); PKG_P8PANELS_VISUAL.TCYCLOGRAM_ADD_TASK_ATTR(RCYCLOGRAM => CG, SNAME => 'ddate_end', SCAPTION => 'Дата окончания', BVISIBLE => true); PKG_P8PANELS_VISUAL.TCYCLOGRAM_ADD_TASK_ATTR(RCYCLOGRAM => CG, SNAME => 'type', SCAPTION => 'Тип', BVISIBLE => false); /* Обходим колонки */ for CLMN in (select T.NAME, T.POS_START, T.POS_END from P8PNL_SMPL_CYCLOGRAM T where T.IDENT = NIDENT and T.TYPE = 0) loop /* Добавляем колонку */ PKG_P8PANELS_VISUAL.TCYCLOGRAM_ADD_COLUMN(RCYCLOGRAM => CG, SNAME => CLMN.NAME, NSTART => CLMN.POS_START, NEND => CLMN.POS_END); end loop; /* Считываем значения для задач проекта */ GROUP_TASK_GET(NIDENT => NIDENT, NFLAG_WO_GROUP => 0, DTASK_DATE_START => DTASK_DATE_START, DTASK_DATE_END => DTASK_DATE_END, NTASK_START => NTASK_START, NTASK_END => NTASK_END); /* Формируем задачу (этап) */ RTASK := PKG_P8PANELS_VISUAL.TCYCLOGRAM_TASK_MAKE(NRN => 1, SCAPTION => 'Задачи проекта', SNAME => 'Задачи проекта', NLINE_NUMB => NLINE_NUMB, NSTART => NTASK_START, NEND => NTASK_END, SBG_COLOR => SCOLOR_WHITE); /* Добавляем атрибуты */ PKG_P8PANELS_VISUAL.TCYCLOGRAM_TASK_ADD_ATTR_VAL(RCYCLOGRAM => CG, RTASK => RTASK, SNAME => 'ddate_start', SVALUE => PKG_XCONVERT.DATE_TO_XML(DVALUE => DTASK_DATE_START), BCLEAR => true); PKG_P8PANELS_VISUAL.TCYCLOGRAM_TASK_ADD_ATTR_VAL(RCYCLOGRAM => CG, RTASK => RTASK, SNAME => 'ddate_end', SVALUE => PKG_XCONVERT.DATE_TO_XML(DVALUE => DTASK_DATE_END)); PKG_P8PANELS_VISUAL.TCYCLOGRAM_TASK_ADD_ATTR_VAL(RCYCLOGRAM => CG, RTASK => RTASK, SNAME => 'type', SVALUE => 0); /* Добавляем задачу в циклограмму */ PKG_P8PANELS_VISUAL.TCYCLOGRAM_ADD_TASK(RCYCLOGRAM => CG, RTASK => RTASK); /* Указываем следующую строку */ NLINE_NUMB := NLINE_NUMB + 1; /* Обходим группы */ for GRP in (select T.RN, T.NAME, ROWNUM RNUM from P8PNL_SMPL_CYCLOGRAM T where T.IDENT = NIDENT and T.TYPE = 1 order by T.RN asc) loop /* Если это вторая группа - сохраним номер строки */ if (GRP.RNUM = 2) then NLINE_NUMB_TMP := NLINE_NUMB; end if; /* Если это третья группа - вернемся на уровень второй группы */ if (GRP.RNUM = 3) then NLINE_NUMB := NLINE_NUMB_TMP; end if; /* Добавляем группу */ PKG_P8PANELS_VISUAL.TCYCLOGRAM_ADD_GROUP(RCYCLOGRAM => CG, SNAME => GRP.NAME, NHEADER_HEIGHT => 30, NHEADER_WIDTH => 200); /* Считываем значения этапа группы */ GROUP_TASK_GET(NIDENT => NIDENT, NGROUP => GRP.RN, DTASK_DATE_START => DTASK_DATE_START, DTASK_DATE_END => DTASK_DATE_END, NTASK_START => NTASK_START, NTASK_END => NTASK_END); /* Формируем задачу (этап) */ RTASK := PKG_P8PANELS_VISUAL.TCYCLOGRAM_TASK_MAKE(NRN => GRP.RN, SCAPTION => 'Этап ' || TO_CHAR(GRP.RNUM), SNAME => 'Этап ' || TO_CHAR(GRP.RNUM), NLINE_NUMB => NLINE_NUMB, NSTART => NTASK_START, NEND => NTASK_END, SBG_COLOR => SBG_TASK_COLOR_GRP, STEXT_COLOR => SCOLOR_WHITE, SHIGHLIGHT_COLOR => SHL_TASK_COLOR_GRP); /* Добавляем атрибуты */ PKG_P8PANELS_VISUAL.TCYCLOGRAM_TASK_ADD_ATTR_VAL(RCYCLOGRAM => CG, RTASK => RTASK, SNAME => 'ddate_start', SVALUE => PKG_XCONVERT.DATE_TO_XML(DVALUE => DTASK_DATE_START), BCLEAR => true); PKG_P8PANELS_VISUAL.TCYCLOGRAM_TASK_ADD_ATTR_VAL(RCYCLOGRAM => CG, RTASK => RTASK, SNAME => 'ddate_end', SVALUE => PKG_XCONVERT.DATE_TO_XML(DVALUE => DTASK_DATE_END)); PKG_P8PANELS_VISUAL.TCYCLOGRAM_TASK_ADD_ATTR_VAL(RCYCLOGRAM => CG, RTASK => RTASK, SNAME => 'type', SVALUE => 1); /* Добавляем задачу в циклограмму */ PKG_P8PANELS_VISUAL.TCYCLOGRAM_ADD_TASK(RCYCLOGRAM => CG, RTASK => RTASK); /* Обходим задачи группы */ for TASK in (select T.RN, T.NAME, T.POS_START, T.POS_END, T.DATE_FROM, T.DATE_TO, ROWNUM RNUM from P8PNL_SMPL_CYCLOGRAM T where T.IDENT = NIDENT and T.TYPE = 2 and T.TASK_GROUP = GRP.RN) loop /* Указываем следующую строку */ NLINE_NUMB := NLINE_NUMB + 1; /* Формируем наименование задачи */ STASK_NAME := 'Работа ' || TO_CHAR(TASK.RNUM) || ' этапа ' || TO_CHAR(GRP.RNUM); /* Формируем задачу */ RTASK := PKG_P8PANELS_VISUAL.TCYCLOGRAM_TASK_MAKE(NRN => TASK.RN, SCAPTION => STASK_NAME, SNAME => STASK_NAME, NLINE_NUMB => NLINE_NUMB, NSTART => TASK.POS_START, NEND => TASK.POS_END, SGROUP => GRP.NAME, SBG_COLOR => SBG_TASK_COLOR_W_GRP, STEXT_COLOR => SCOLOR_WHITE, SHIGHLIGHT_COLOR => SHL_TASK_COLOR_W_GRP); /* Добавляем атрибуты */ PKG_P8PANELS_VISUAL.TCYCLOGRAM_TASK_ADD_ATTR_VAL(RCYCLOGRAM => CG, RTASK => RTASK, SNAME => 'ddate_start', SVALUE => PKG_XCONVERT.DATE_TO_XML(DVALUE => TASK.DATE_FROM), BCLEAR => true); PKG_P8PANELS_VISUAL.TCYCLOGRAM_TASK_ADD_ATTR_VAL(RCYCLOGRAM => CG, RTASK => RTASK, SNAME => 'ddate_end', SVALUE => PKG_XCONVERT.DATE_TO_XML(DVALUE => TASK.DATE_TO)); PKG_P8PANELS_VISUAL.TCYCLOGRAM_TASK_ADD_ATTR_VAL(RCYCLOGRAM => CG, RTASK => RTASK, SNAME => 'type', SVALUE => 2); /* Добавляем задачу в циклограмму */ PKG_P8PANELS_VISUAL.TCYCLOGRAM_ADD_TASK(RCYCLOGRAM => CG, RTASK => RTASK); end loop; /* Указываем следующую строку */ NLINE_NUMB := NLINE_NUMB + 1; end loop; /* Указываем следующую строку */ NLINE_NUMB := NLINE_NUMB + 1; /* Считываем значения для обособленных задач */ GROUP_TASK_GET(NIDENT => NIDENT, NFLAG_WO_GROUP => 1, DTASK_DATE_START => DTASK_DATE_START, DTASK_DATE_END => DTASK_DATE_END, NTASK_START => NTASK_START, NTASK_END => NTASK_END); /* Формируем задачу (этап) */ RTASK := PKG_P8PANELS_VISUAL.TCYCLOGRAM_TASK_MAKE(NRN => 1, SCAPTION => 'Обособленные задачи', SNAME => 'Обособленные задачи', NLINE_NUMB => NLINE_NUMB, NSTART => NTASK_START, NEND => NTASK_END, SBG_COLOR => SCOLOR_WHITE); /* Добавляем атрибуты */ PKG_P8PANELS_VISUAL.TCYCLOGRAM_TASK_ADD_ATTR_VAL(RCYCLOGRAM => CG, RTASK => RTASK, SNAME => 'ddate_start', SVALUE => PKG_XCONVERT.DATE_TO_XML(DVALUE => DTASK_DATE_START), BCLEAR => true); PKG_P8PANELS_VISUAL.TCYCLOGRAM_TASK_ADD_ATTR_VAL(RCYCLOGRAM => CG, RTASK => RTASK, SNAME => 'ddate_end', SVALUE => PKG_XCONVERT.DATE_TO_XML(DVALUE => DTASK_DATE_END)); PKG_P8PANELS_VISUAL.TCYCLOGRAM_TASK_ADD_ATTR_VAL(RCYCLOGRAM => CG, RTASK => RTASK, SNAME => 'type', SVALUE => 0); /* Добавляем задачу в циклограмму */ PKG_P8PANELS_VISUAL.TCYCLOGRAM_ADD_TASK(RCYCLOGRAM => CG, RTASK => RTASK); /* Указываем следующую строку */ NLINE_NUMB := NLINE_NUMB + 1; /* Цикл по обособленным задачам */ for REC in (select T.RN, T.NAME, T.POS_START, T.POS_END, T.DATE_FROM, T.DATE_TO, ROWNUM RNUM from P8PNL_SMPL_CYCLOGRAM T where T.IDENT = NIDENT and T.TYPE = 2 and T.TASK_GROUP is null) loop /* Формируем наименование задачи */ STASK_NAME := 'Работа ' || TO_CHAR(REC.RNUM) || ' без этапа '; /* Формируем задачу */ RTASK := PKG_P8PANELS_VISUAL.TCYCLOGRAM_TASK_MAKE(NRN => REC.RN, SCAPTION => STASK_NAME, SNAME => STASK_NAME, NLINE_NUMB => NLINE_NUMB, NSTART => REC.POS_START, NEND => REC.POS_END, SBG_COLOR => SBG_TASK_COLOR_WO_GRP, STEXT_COLOR => STEXT_COLOR_TASK_WO_GRP); /* Добавляем атрибуты */ PKG_P8PANELS_VISUAL.TCYCLOGRAM_TASK_ADD_ATTR_VAL(RCYCLOGRAM => CG, RTASK => RTASK, SNAME => 'ddate_start', SVALUE => PKG_XCONVERT.DATE_TO_XML(DVALUE => REC.DATE_FROM), BCLEAR => true); PKG_P8PANELS_VISUAL.TCYCLOGRAM_TASK_ADD_ATTR_VAL(RCYCLOGRAM => CG, RTASK => RTASK, SNAME => 'ddate_end', SVALUE => PKG_XCONVERT.DATE_TO_XML(DVALUE => REC.DATE_TO)); PKG_P8PANELS_VISUAL.TCYCLOGRAM_TASK_ADD_ATTR_VAL(RCYCLOGRAM => CG, RTASK => RTASK, SNAME => 'type', SVALUE => 2); /* Добавляем задачу в циклограмму */ PKG_P8PANELS_VISUAL.TCYCLOGRAM_ADD_TASK(RCYCLOGRAM => CG, RTASK => RTASK); end loop; /* Формируем список */ COUT := PKG_P8PANELS_VISUAL.TCYCLOGRAM_TO_XML(RCYCLOGRAM => CG); end CYCLOGRAM; /* Изменение задачи циклограммы */ procedure CYCLOGRAM_TASK_MODIFY ( NIDENT in number, -- Идентификатор буфера NRN in number, -- Рег. номер записи SDATE_FROM in varchar2, -- Дата начала (в строковом представлении) SDATE_TO in varchar2 -- Дата окончания (в строковом представлении) ) is DDATE_FROM PKG_STD.TLDATE; -- Дата начала DDATE_TO PKG_STD.TLDATE; -- Дата окончания NYEAR PKG_STD.TNUMBER; -- Текущий год DCYCLOGRAM_START PKG_STD.TLDATE; -- Дата начала циклограммы NSTART PKG_STD.TNUMBER; -- Позиция начала элемента NEND PKG_STD.TNUMBER; -- Позиция окончания элемента begin /* Фиксируем текущий год */ NYEAR := EXTRACT(year from sysdate); /* Переводим даты */ DDATE_FROM := TO_DATE(SDATE_FROM, 'dd.mm.yyyy'); DDATE_TO := TO_DATE(SDATE_TO, 'dd.mm.yyyy'); /* Если дата начала выходит за границы года */ if (D_YEAR(DDATE => DDATE_FROM) <> NYEAR) then P_EXCEPTION(0, 'Дата начала задачи выходит за границы текущего года (%s).', NYEAR); end if; /* Если дата окончания выходит за границы года */ if (D_YEAR(DDATE => DDATE_TO) <> NYEAR) then P_EXCEPTION(0, 'Дата окончания задачи выходит за границы текущего года (%s).', NYEAR); end if; /* Дата окончания не может быть меньше даты начала */ if (DDATE_TO < DDATE_FROM) then P_EXCEPTION(0, 'Дата окончания не может быть меньше даты начала.'); end if; /* Фиксируем дату начала циклограммы */ DCYCLOGRAM_START := TO_DATE('01.01.' || NYEAR, 'dd.mm.yyyy'); /* Рассчитываем новую позицию начала */ NSTART := (DDATE_FROM - DCYCLOGRAM_START) * NCG_MULTIPLIER; /* Рассчитываем новую позицию окончания */ NEND := NSTART + ((DDATE_TO - DDATE_FROM + 1) * NCG_MULTIPLIER); /* Считываем запись */ for REC in (select T.* from P8PNL_SMPL_CYCLOGRAM T where T.RN = NRN and T.IDENT = NIDENT) loop /* Обновляем запись циклограммы */ CYCLOGRAM_BASE_UPDATE(NIDENT => REC.IDENT, NRN => REC.RN, NTYPE => REC.TYPE, SNAME => REC.NAME, NPOS_START => NSTART, NPOS_END => NEND, DDATE_FROM => DDATE_FROM, DDATE_TO => DDATE_TO, NTASK_GROUP => REC.TASK_GROUP); end loop; end CYCLOGRAM_TASK_MODIFY; end PKG_P8PANELS_SAMPLES; /