diff --git a/db/PKG_P8PANELS.pck b/db/PKG_P8PANELS.pck new file mode 100644 index 0000000..8b429af --- /dev/null +++ b/db/PKG_P8PANELS.pck @@ -0,0 +1,27 @@ +create or replace package PKG_P8PANELS as + + /* Исполнение действий клиентских приложений */ + procedure PROCESS + ( + CIN in clob, -- Входные параметры + COUT out clob -- Результат + ); + +end PKG_P8PANELS; +/ +create or replace package body PKG_P8PANELS as + + /* Исполнение действий клиентских приложений */ + procedure PROCESS + ( + CIN in clob, -- Входные параметры + COUT out clob -- Результат + ) + is + begin + /* Базовое исполнение действия */ + PKG_P8PANELS_BASE.PROCESS(CIN => CIN, COUT => COUT); + end PROCESS; + +end PKG_P8PANELS; +/ diff --git a/db/PKG_P8PANELS_BASE.pck b/db/PKG_P8PANELS_BASE.pck new file mode 100644 index 0000000..6f9cf9a --- /dev/null +++ b/db/PKG_P8PANELS_BASE.pck @@ -0,0 +1,814 @@ +create or replace package PKG_P8PANELS_BASE as + + /*Константы - Типовой постфикс тега для массива (при переводе XML -> JSON) */ + SXML_ALWAYS_ARRAY_POSTFIX constant PKG_STD.TSTRING := '__SYSTEM__ARRAY__'; + + /* Конвертация строки в число */ + function UTL_S2N + ( + SVALUE in varchar2 -- Конвертируемое строковое значение + ) return number; -- Конвертированное число + + /* Конвертация даты в число */ + function UTL_S2D + ( + SVALUE in varchar2 -- Конвертируемое строковое значение + ) return date; -- Конвертированная дата + + /* Базовое исполнение действий */ + procedure PROCESS + ( + CIN in clob, -- Входные параметры + COUT out clob -- Результат + ); + +end PKG_P8PANELS_BASE; +/ +create or replace package body PKG_P8PANELS_BASE as + + /* Константы - коды дествий запросов */ + SRQ_ACTION_EXEC_STORED constant PKG_STD.TSTRING := 'EXEC_STORED'; -- Запрос на исполнение хранимой процедуры + + /* Константы - тэги запросов */ + SRQ_TAG_XREQUEST constant PKG_STD.TSTRING := 'XREQUEST'; -- Корневой тэг запроса + SRQ_TAG_XPAYLOAD constant PKG_STD.TSTRING := 'XPAYLOAD'; -- Тэг для данных запроса + SRQ_TAG_SACTION constant PKG_STD.TSTRING := 'SACTION'; -- Тэг для действия запроса + SRQ_TAG_SSTORED constant PKG_STD.TSTRING := 'SSTORED'; -- Тэг для имени хранимого объекта в запросе + SRQ_TAG_SRESP_ARG constant PKG_STD.TSTRING := 'SRESP_ARG'; -- Тэг для имени аргумента, формирующего данные ответа + SRQ_TAG_XARGUMENTS constant PKG_STD.TSTRING := 'XARGUMENTS'; -- Тэг для списка аргументов хранимого объекта/выборки в запросе + SRQ_TAG_XARGUMENT constant PKG_STD.TSTRING := 'XARGUMENT'; -- Тэг для аргумента хранимого объекта/выборки в запросе + SRQ_TAG_SNAME constant PKG_STD.TSTRING := 'SNAME'; -- Тэг для наименования в запросе + SRQ_TAG_SDATA_TYPE constant PKG_STD.TSTRING := 'SDATA_TYPE'; -- Тэг для типа данных в запросе + SRQ_TAG_VALUE constant PKG_STD.TSTRING := 'VALUE'; -- Тэг для значения в запросе + + /* Константы - тэги ответов */ + SRESP_TAG_XPAYLOAD constant PKG_STD.TSTRING := 'XPAYLOAD'; -- Тэг для данных ответа + SRESP_TAG_XOUT_ARGUMENTS constant PKG_STD.TSTRING := 'XOUT_ARGUMENTS'; -- Тэг для выходных аргументов хранимого объекта в ответе + SRESP_TAG_SDATA_TYPE constant PKG_STD.TSTRING := 'SDATA_TYPE'; -- Тэг для типа данных в ответе + SRESP_TAG_VALUE constant PKG_STD.TSTRING := 'VALUE'; -- Тэг для значения в ответе + SRESP_TAG_SNAME constant PKG_STD.TSTRING := 'SNAME'; -- Тэг для наименования в ответе + + /* Константы - типы данных */ + SDATA_TYPE_STR constant PKG_STD.TSTRING := 'STR'; -- Тип данных "строка" + SDATA_TYPE_NUMB constant PKG_STD.TSTRING := 'NUMB'; -- Тип данных "число" + SDATA_TYPE_DATE constant PKG_STD.TSTRING := 'DATE'; -- Тип данных "дата" + SDATA_TYPE_CLOB constant PKG_STD.TSTRING := 'CLOB'; -- Тип данных "текст" + + /* Константы - состояния объектов БД */ + SDB_OBJECT_STATE_VALID constant PKG_STD.TSTRING := 'VALID'; -- Объект валиден + + /* Типы данных - аргументы */ + type TARGUMENT is record + ( + SNAME PKG_STD.TSTRING, -- Наименование + SDATA_TYPE PKG_STD.TSTRING, -- Тип данных (см. константы SPWS_DATA_TYPE_*) + SVALUE PKG_STD.TSTRING, -- Значение (строка) + NVALUE PKG_STD.TLNUMBER, -- Значение (число) + DVALUE PKG_STD.TLDATE, -- Значение (дата) + CVALUE clob -- Значение (текст) + ); + + /* Типы данных - коллекция аргументов запроса */ + type TARGUMENTS is table of TARGUMENT; + + /* Конвертация строки в число */ + function UTL_S2N + ( + SVALUE in varchar2 -- Конвертируемое строковое значение + ) return number -- Конвертированное число + is + NVALUE PKG_STD.TNUMBER; -- Результат работы + begin + /* Пробуем конвертировать */ + NVALUE := TO_NUMBER(replace(SVALUE, ',', '.')); + /* Отдаём результат */ + return NVALUE; + exception + when others then + P_EXCEPTION(0, 'Неверный формат числа (%s).', SVALUE); + end UTL_S2N; + + /* Конвертация даты в число */ + function UTL_S2D + ( + SVALUE in varchar2 -- Конвертируемое строковое значение + ) return date -- Конвертированная дата + is + DVALUE PKG_STD.TLDATE; -- Результат работы + begin + /* Пробуем конвертировать */ + begin + DVALUE := TO_DATE(SVALUE, 'YYYY-MM-DD'); + exception + when others then + begin + DVALUE := TO_DATE(SVALUE, 'YYYY/MM/DD'); + exception + when others then + begin + DVALUE := TO_DATE(SVALUE, 'DD.MM.YYYY'); + exception + when others then + DVALUE := TO_DATE(SVALUE, 'DD/MM/YYYY'); + end; + end; + end; + /* Отдаём результат */ + return DVALUE; + exception + when others then + P_EXCEPTION(0, 'Неверный формат даты (%s).', SVALUE); + end UTL_S2D; + + /* Формирование сообщения об отсутствии значения */ + function MSG_NO_DATA_MAKE + ( + SPATH in varchar2 := null, -- Путь по которому ожидалось значение + SMESSAGE_OBJECT in varchar2 := null -- Наимемнование объекта для формулирования сообщения об ошибке + ) return varchar2 -- Сформированное сообщение об ошибке + is + SPATH_ PKG_STD.TSTRING; -- Буфер для пути + SMESSAGE_OBJECT_ PKG_STD.TSTRING; -- Буфер для наименования объекта + begin + /* Подготовим путь к выдаче */ + if (SPATH is not null) then + SPATH_ := ' (' || SPATH || ')'; + end if; + /* Подготовим наименование объекта к выдаче */ + if (SMESSAGE_OBJECT is not null) then + SMESSAGE_OBJECT_ := ' элемента "' || SMESSAGE_OBJECT || '"'; + else + SMESSAGE_OBJECT_ := ' элемента'; + end if; + /* Вернём сформированное сообщение */ + return 'Не указано значение' || SMESSAGE_OBJECT_ || SPATH_ || '.'; + end MSG_NO_DATA_MAKE; + + /* Конвертация стандартного типа данных (PKG_STD) в тип данных сервиса (PWS) */ + function STD_DATA_TYPE_TO_STR + ( + NSTD_DATA_TYPE in number -- Станартный тип данных + ) return varchar2 -- Соответствующий тип данных сервиса + is + SRES PKG_STD.TSTRING; -- Буфер для результата + begin + /* Работаем от типа данных */ + case NSTD_DATA_TYPE + /* Строка */ + when PKG_STD.DATA_TYPE_STR then + SRES := SDATA_TYPE_STR; + /* Число */ + when PKG_STD.DATA_TYPE_NUM then + SRES := SDATA_TYPE_NUMB; + /* Дата */ + when PKG_STD.DATA_TYPE_DATE then + SRES := SDATA_TYPE_DATE; + /* Текст */ + when PKG_STD.DATA_TYPE_CLOB then + SRES := SDATA_TYPE_CLOB; + /* Неизвестный тип данных */ + else + P_EXCEPTION(0, 'Тип данных "%s" не поддерживается.', TO_CHAR(NSTD_DATA_TYPE)); + end case; + /* Возвращаем результат */ + return SRES; + end STD_DATA_TYPE_TO_STR; + + /* Считывание значения ветки XML (строка) */ + function NODE_SVAL_GET + ( + XROOT in PKG_XPATH.TNODE, -- Корневая ветка для считывания значения + SPATH in varchar2, -- Путь для считывания данных + NREQUIRED in number := 0, -- Флаг выдачи сообщения об ошибке в случае отсутствия значения (0 - не выдавать, 1 - выдавать) + SMESSAGE_OBJECT in varchar2 := null -- Наимемнование объекта для формулирования сообщения об ошибке + ) return varchar2 -- Считанное значение + is + XNODE PKG_XPATH.TNODE; -- Искомая ветка со значением (подходящая под шаблон) + SVAL PKG_STD.TSTRING; -- Результат работы + begin + /* Найдем нужную ветку по шаблону */ + XNODE := PKG_XPATH.SINGLE_NODE(RPARENT_NODE => XROOT, SPATTERN => SPATH); + /* Если там нет ничего */ + if (PKG_XPATH.IS_NULL(RNODE => XNODE)) then + /* Его и вернём */ + SVAL := null; + else + /* Что-то есть - читаем данные */ + begin + SVAL := PKG_XPATH.VALUE(RNODE => XNODE); + exception + when others then + P_EXCEPTION(0, 'Неверный формат строки (%s).', SPATH); + end; + end if; + /* Если значения нет, а оно должно быть - скажем об этом */ + if ((SVAL is null) and (NREQUIRED = 1)) then + P_EXCEPTION(0, MSG_NO_DATA_MAKE(SPATH => SPATH, SMESSAGE_OBJECT => SMESSAGE_OBJECT)); + end if; + /* Отдаём результат */ + return SVAL; + end NODE_SVAL_GET; + + /* Считывание значения ветки XML (число) */ + function NODE_NVAL_GET + ( + XROOT in PKG_XPATH.TNODE, -- Корневая ветка для считывания значения + SPATH in varchar2, -- Путь для считывания данных + NREQUIRED in number := 0, -- Флаг выдачи сообщения об ошибке в случае отсутствия значения (0 - не выдавать, 1 - выдавать) + SMESSAGE_OBJECT in varchar2 := null -- Наимемнование объекта для формулирования сообщения об ошибке + ) return number -- Считанное значение + is + XNODE PKG_XPATH.TNODE; -- Искомая ветка со значением (подходящая под шаблон) + NVAL PKG_STD.TLNUMBER; -- Результат работы + begin + /* Найдем нужную ветку по шаблону */ + XNODE := PKG_XPATH.SINGLE_NODE(RPARENT_NODE => XROOT, SPATTERN => SPATH); + /* Если там нет ничего */ + if (PKG_XPATH.IS_NULL(RNODE => XNODE)) then + /* Его и вернём */ + NVAL := null; + else + /* Что-то есть - читаем данные */ + begin + NVAL := PKG_XPATH.VALUE_NUM(RNODE => XNODE); + exception + when others then + P_EXCEPTION(0, 'Неверный формат числа (%s).', SPATH); + end; + end if; + /* Если значения нет, а оно должно быть - скажем об этом */ + if ((NVAL is null) and (NREQUIRED = 1)) then + P_EXCEPTION(0, MSG_NO_DATA_MAKE(SPATH => SPATH, SMESSAGE_OBJECT => SMESSAGE_OBJECT)); + end if; + /* Отдаём результат */ + return NVAL; + end NODE_NVAL_GET; + + /* Считывание значения ветки XML (дата) */ + function NODE_DVAL_GET + ( + XROOT in PKG_XPATH.TNODE, -- Корневая ветка для считывания значения + SPATH in varchar2, -- Путь для считывания данных + NREQUIRED in number := 0, -- Флаг выдачи сообщения об ошибке в случае отсутствия значения (0 - не выдавать, 1 - выдавать) + SMESSAGE_OBJECT in varchar2 := null -- Наимемнование объекта для формулирования сообщения об ошибке + ) return date -- Считанное значение + is + XNODE PKG_XPATH.TNODE; -- Искомая ветка со значением (подходящая под шаблон) + DVAL PKG_STD.TLDATE; -- Результат работы + begin + /* Найдем нужную ветку по шаблону */ + XNODE := PKG_XPATH.SINGLE_NODE(RPARENT_NODE => XROOT, SPATTERN => SPATH); + /* Если там нет ничего */ + if (PKG_XPATH.IS_NULL(RNODE => XNODE)) then + /* Его и вернём */ + DVAL := null; + else + /* Что-то есть - читаем данные */ + begin + DVAL := PKG_XPATH.VALUE_DATE(RNODE => XNODE); + exception + when others then + begin + DVAL := PKG_XPATH.VALUE_TS(RNODE => XNODE); + exception + when others then + begin + DVAL := PKG_XPATH.VALUE_TZ(RNODE => XNODE); + exception + when others then + P_EXCEPTION(0, + 'Неверный формат даты (%s). Ожидалось: YYYY-MM-DD"T"HH24:MI:SS.FF3tzh:tzm, YYYY-MM-DD"T"HH24:MI:SS.FF3, YYYY-MM-DD"T"HH24:MI:SS, YYYY-MM-DD.', + SPATH); + end; + end; + end; + end if; + /* Если значения нет, а оно должно быть - скажем об этом */ + if ((DVAL is null) and (NREQUIRED = 1)) then + P_EXCEPTION(0, MSG_NO_DATA_MAKE(SPATH => SPATH, SMESSAGE_OBJECT => SMESSAGE_OBJECT)); + end if; + /* Отдаём результат */ + return DVAL; + end NODE_DVAL_GET; + + /* Считывание значения ветки XML (текст) */ + function NODE_CVAL_GET + ( + XROOT in PKG_XPATH.TNODE, -- Корневая ветка для считывания значения + SPATH in varchar2, -- Путь для считывания данных + NREQUIRED in number := 0, -- Флаг выдачи сообщения об ошибке в случае отсутствия значения (0 - не выдавать, 1 - выдавать) + SMESSAGE_OBJECT in varchar2 := null -- Наимемнование объекта для формулирования сообщения об ошибке + ) return clob -- Считанное значение + is + XNODE PKG_XPATH.TNODE; -- Искомая ветка со значением (подходящая под шаблон) + CVAL clob; -- Результат работы + begin + /* Найдем нужную ветку по шаблону */ + XNODE := PKG_XPATH.SINGLE_NODE(RPARENT_NODE => XROOT, SPATTERN => SPATH); + /* Если там нет ничего */ + if (PKG_XPATH.IS_NULL(RNODE => XNODE)) then + /* Его и вернём */ + CVAL := null; + else + /* Что-то есть - читаем данные */ + begin + CVAL := PKG_XPATH.VALUE_CLOB(RNODE => XNODE); + exception + when others then + P_EXCEPTION(0, 'Неверный формат текстовых данных (%s).', SPATH); + end; + end if; + /* Если значения нет, а оно должно быть - скажем об этом */ + if ((CVAL is null) and (NREQUIRED = 1)) then + P_EXCEPTION(0, MSG_NO_DATA_MAKE(SPATH => SPATH, SMESSAGE_OBJECT => SMESSAGE_OBJECT)); + end if; + /* Отдаём результат */ + return CVAL; + end NODE_CVAL_GET; + + /* Считывание аргумента из коллекции */ + function TARGUMENTS_GET + ( + ARGUMENTS in TARGUMENTS, -- Коллекция аргументов + SARGUMENT in varchar2, -- Код аргумента + NREQUIRED in number := 0 -- Флаг выдачи сообщения об ошибке в случае отсутствия значения (0 - не выдавать, 1 - выдавать) + ) return TARGUMENT -- Найденный аргумент + is + begin + /* Если данные в коллекции есть */ + if ((ARGUMENTS is not null) and (ARGUMENTS.COUNT > 0)) then + /* Обходим её */ + for I in ARGUMENTS.FIRST .. ARGUMENTS.LAST + loop + /* Если встретился нужный аргумент */ + if (ARGUMENTS(I).SNAME = SARGUMENT) then + /* Вернём его */ + return ARGUMENTS(I); + end if; + end loop; + end if; + /* Если мы здесь - аргумент не нашелся, будем выдавать сообщение об ошибке если он был обязательным */ + if (NREQUIRED = 1) then + P_EXCEPTION(0, 'Не задан обязательный аргумент "%s".', SARGUMENT); + else + /* Он не обязательный - вернём отсутствие данных */ + return null; + end if; + end TARGUMENTS_GET; + + /* Считывание значения аргумента из коллекции (строка) */ + function TARGUMENTS_SVAL_GET + ( + ARGUMENTS in TARGUMENTS, -- Коллекция аргументов + SARGUMENT in varchar2, -- Код аргумента + NREQUIRED in number := 0 -- Флаг выдачи сообщения об ошибке в случае отсутствия значения (0 - не выдавать, 1 - выдавать) + ) return varchar2 -- Значение аргумента + is + begin + /* Считаем и вернём значение */ + return TARGUMENTS_GET(ARGUMENTS => ARGUMENTS, SARGUMENT => SARGUMENT, NREQUIRED => NREQUIRED).SVALUE; + end TARGUMENTS_SVAL_GET; + + /* Считывание значения параметра из запроса (число) */ + function TARGUMENTS_NVAL_GET + ( + ARGUMENTS in TARGUMENTS, -- Коллекция аргументов + SARGUMENT in varchar2, -- Код аргумента + NREQUIRED in number := 0 -- Флаг выдачи сообщения об ошибке в случае отсутствия значения (0 - не выдавать, 1 - выдавать) + ) return number -- Значение аргумента + is + begin + /* Считаем и вернём значение */ + return TARGUMENTS_GET(ARGUMENTS => ARGUMENTS, SARGUMENT => SARGUMENT, NREQUIRED => NREQUIRED).NVALUE; + end TARGUMENTS_NVAL_GET; + + /* Считывание значения параметра из запроса (дата) */ + function TARGUMENTS_DVAL_GET + ( + ARGUMENTS in TARGUMENTS, -- Коллекция аргументов + SARGUMENT in varchar2, -- Код аргумента + NREQUIRED in number := 0 -- Флаг выдачи сообщения об ошибке в случае отсутствия значения (0 - не выдавать, 1 - выдавать) + ) return date -- Значение аргумента + is + begin + /* Считаем и вернём значение */ + return TARGUMENTS_GET(ARGUMENTS => ARGUMENTS, SARGUMENT => SARGUMENT, NREQUIRED => NREQUIRED).DVALUE; + end TARGUMENTS_DVAL_GET; + + /* Считывание значения параметра из запроса (текст) */ + function TARGUMENTS_CVAL_GET + ( + ARGUMENTS in TARGUMENTS, -- Коллекция аргументов + SARGUMENT in varchar2, -- Код аргумента + NREQUIRED in number := 0 -- Флаг выдачи сообщения об ошибке в случае отсутствия значения (0 - не выдавать, 1 - выдавать) + ) return clob -- Значение аргумента + is + begin + /* Считаем и вернём значение */ + return TARGUMENTS_GET(ARGUMENTS => ARGUMENTS, SARGUMENT => SARGUMENT, NREQUIRED => NREQUIRED).CVALUE; + end TARGUMENTS_CVAL_GET; + + /* Получение корневого элемента тела запроса */ + function RQ_ROOT_GET + ( + CRQ in clob -- Запрос + ) return PKG_XPATH.TNODE -- Корневой элемент первой ветки тела документа + is + begin + /* Возвращаем корневой элемент документа */ + return PKG_XPATH.ROOT_NODE(RDOCUMENT => PKG_XPATH.PARSE_FROM_CLOB(LCXML => CRQ)); + end RQ_ROOT_GET; + + /* Получение пути к запросу */ + function RQ_PATH_GET + return varchar2 -- Путь к запросу + is + begin + return '/' || SRQ_TAG_XREQUEST; + end RQ_PATH_GET; + + /* Получение пути к элементу действия запроса */ + function RQ_ACTION_PATH_GET + return varchar2 -- Путь к элементу действия запроса + is + begin + return RQ_PATH_GET() || '/' || SRQ_TAG_SACTION; + end RQ_ACTION_PATH_GET; + + /* Получение кода действия запроса */ + function RQ_ACTION_GET + ( + XRQ_ROOT in PKG_XPATH.TNODE := null, -- Корневая ветка запроса + NREQUIRED in number := 0 -- Флаг выдачи сообщения об ошибке в случае отсутствия значения (0 - не выдавать, 1 - выдавать) + ) return varchar2 -- Код действия запроса + is + begin + /* Вернем значение элемента тела с кодом действия */ + return NODE_SVAL_GET(XROOT => XRQ_ROOT, + SPATH => RQ_ACTION_PATH_GET(), + NREQUIRED => NREQUIRED, + SMESSAGE_OBJECT => 'Код действия'); + end RQ_ACTION_GET; + + /* Получение пути к параметрам запроса */ + function RQ_PAYLOAD_PATH_GET + return varchar2 -- Путь к параметрам запроса + is + begin + /* Вернем значение */ + return RQ_PATH_GET() || '/' || SRQ_TAG_XPAYLOAD; + end RQ_PAYLOAD_PATH_GET; + + /* Получение пути к элкменту параметров запроса */ + function RQ_PAYLOAD_ITEM_PATH_GET + ( + SITEM_TAG in varchar2 -- Тэг элемента + ) + return varchar2 -- Путь к элементу параметров запроса + is + begin + /* Вернем значение */ + return RQ_PAYLOAD_PATH_GET() || '/' || SITEM_TAG; + end RQ_PAYLOAD_ITEM_PATH_GET; + + /* Считывание наименования исполняемого хранимого объекта из запроса */ + function RQ_PAYLOAD_STORED_GET + ( + XRQ_ROOT in PKG_XPATH.TNODE := null, -- Корневая ветка запроса + NREQUIRED in number := 0 -- Флаг выдачи сообщения об ошибке в случае отсутствия значения (0 - не выдавать, 1 - выдавать) + ) return varchar2 -- Наименование исполняемого хранимого объекта из запроса + is + begin + /* Вернем значение элемента тела с наименованием хранимого объекта */ + return NODE_SVAL_GET(XROOT => XRQ_ROOT, + SPATH => RQ_PAYLOAD_ITEM_PATH_GET(SITEM_TAG => SRQ_TAG_SSTORED), + NREQUIRED => NREQUIRED, + SMESSAGE_OBJECT => 'Наименование процедуры/функции'); + end RQ_PAYLOAD_STORED_GET; + + /* Проверка исполняемого хранимого объекта из запроса */ + procedure RQ_PAYLOAD_STORED_CHECK + ( + XRQ_ROOT in PKG_XPATH.TNODE, -- Корневая ветка запроса + SSTORED in varchar2 := null -- Наименование проверяемого хранимого объекта (null - автоматическое считывание из запроса) + ) + is + SSTORED_ PKG_STD.TSTRING; -- Буфер для наименования проверяемого хранимого объекта + RSTORED PKG_OBJECT_DESC.TSTORED; -- Описание хранимого объекта из БД + SPROCEDURE PKG_STD.TSTRING; -- Буфер для наименования хранимой процедуры + SPACKAGE PKG_STD.TSTRING; -- Буфер для наименования пакета, содержащего хранимый объект + RPACKAGE PKG_OBJECT_DESC.TPACKAGE; -- Описание пакета, содержащего хранимый объект + begin + /* Считаем наименование объекта из запроса или используем переданное в параметрах */ + if (SSTORED is not null) then + SSTORED_ := SSTORED; + else + SSTORED_ := RQ_PAYLOAD_STORED_GET(XRQ_ROOT => XRQ_ROOT, NREQUIRED => 1); + end if; + /* Проверим, что это процедура или функция и она вообще существует */ + if (PKG_OBJECT_DESC.EXISTS_STORED(SSTORED_NAME => SSTORED_) = 0) then + P_EXCEPTION(0, + 'Хранимая процедура/функция "' || SSTORED_ || '" не определена.'); + else + /* Проверим, что в имени нет ссылки на пакет */ + PKG_EXS.UTL_STORED_PARSE_LINK(SSTORED => SSTORED_, SPROCEDURE => SPROCEDURE, SPACKAGE => SPACKAGE); + /* Если в имени есть ссылка на пакет - сначала проверим его состояние */ + if (SPACKAGE is not null) then + RPACKAGE := PKG_OBJECT_DESC.DESC_PACKAGE(SPACKAGE_NAME => SPACKAGE, BRAISE_ERROR => false); + end if; + /* Если есть ссылка на пакет, или он не валиден - это ошибка */ + if ((SPACKAGE is not null) and (RPACKAGE.STATUS <> SDB_OBJECT_STATE_VALID)) then + P_EXCEPTION(0, + 'Пакет "' || SPACKAGE || + '", содержащий хранимую процедуру/функцию, невалиден. Обращение к объекту невозможно.'); + else + /* Нет ссылки на пакет или он валиден - проверяем глубже, получим описание объекта из БД */ + RSTORED := PKG_OBJECT_DESC.DESC_STORED(SSTORED_NAME => SSTORED_, BRAISE_ERROR => false); + /* Проверим, что валидна */ + if (RSTORED.STATUS <> SDB_OBJECT_STATE_VALID) then + P_EXCEPTION(0, + 'Хранимая процедура/функция "' || SSTORED_ || '" невалидна. Обращение к объекту невозможно.'); + else + /* Проверим, что это клиентский объект */ + if (PKG_OBJECT_DESC.EXISTS_PRIV_EXECUTE(SSTORED_NAME => COALESCE(RSTORED.PACKAGE_NAME, SSTORED_)) = 0) then + P_EXCEPTION(0, + 'Хранимая процедура/функция "' || SSTORED_ || + '" не является клиентской. Обращение к объекту невозможно.'); + end if; + end if; + end if; + end if; + end RQ_PAYLOAD_STORED_CHECK; + + /* Считывание списка аргументов из запроса */ + function RQ_PAYLOAD_ARGUMENTS_GET + ( + XRQ_ROOT in PKG_XPATH.TNODE, -- Корневая ветка запроса + NREQUIRED in number := 0 -- Флаг выдачи сообщения об ошибке в случае отсутствия значения (0 - не выдавать, 1 - выдавать) + ) return TARGUMENTS -- Коллекция аргументов из запроса + is + RES TARGUMENTS; -- Результат работы + SRQ_ARGUMENTS_PATH PKG_STD.TSTRING; -- Полный путь до аргументов выборки в запросе + XRQ_ARGUMENTS PKG_XPATH.TNODES; -- Коллекция элементов документа запроса с аргументами + XRQ_ARGUMENT PKG_XPATH.TNODE; -- Элемент документа запроса с аргументов + begin + /* Инициализируем результат */ + RES := TARGUMENTS(); + /* Сформируем полный путь до аргументов в выборке */ + SRQ_ARGUMENTS_PATH := RQ_PAYLOAD_ITEM_PATH_GET(SITEM_TAG => SRQ_TAG_XARGUMENTS) || '/' || SRQ_TAG_XARGUMENT; + /* Считаем коллекцию аргументов из документа */ + XRQ_ARGUMENTS := PKG_XPATH.LIST_NODES(RPARENT_NODE => XRQ_ROOT, SPATTERN => SRQ_ARGUMENTS_PATH); + /* Обходим коллекцию аргументов из документа */ + for I in 1 .. PKG_XPATH.COUNT_NODES(RNODES => XRQ_ARGUMENTS) + loop + /* Берем очередной аргумент */ + XRQ_ARGUMENT := PKG_XPATH.ITEM_NODE(RNODES => XRQ_ARGUMENTS, INUMBER => I); + /* Добавляем его в выходную коллекцию */ + RES.EXTEND(); + RES(RES.LAST).SNAME := NODE_SVAL_GET(XROOT => XRQ_ARGUMENT, SPATH => SRQ_TAG_SNAME); + RES(RES.LAST).SDATA_TYPE := NODE_SVAL_GET(XROOT => XRQ_ARGUMENT, SPATH => SRQ_TAG_SDATA_TYPE); + /* Проверим корректность данных - наименование */ + if (RES(RES.LAST).SNAME is null) then + P_EXCEPTION(0, + 'Для аргумента не задано наименование (%s).', + SRQ_ARGUMENTS_PATH || '/' || SRQ_TAG_SNAME); + end if; + /* Проверим корректность данных - тип данных */ + if (RES(RES.LAST).SDATA_TYPE is null) then + P_EXCEPTION(0, + 'Для аргумента "%s" не задан тип данных (%s).', + RES(RES.LAST).SNAME, + SRQ_ARGUMENTS_PATH || '/' || SRQ_TAG_SDATA_TYPE); + end if; + /* Считаем значение в зависимости от типа данных */ + case + /* Строка */ + when (RES(RES.LAST).SDATA_TYPE = SDATA_TYPE_STR) then + RES(RES.LAST).SVALUE := NODE_SVAL_GET(XROOT => XRQ_ARGUMENT, SPATH => SRQ_TAG_VALUE); + /* Число */ + when (RES(RES.LAST).SDATA_TYPE = SDATA_TYPE_NUMB) then + RES(RES.LAST).NVALUE := NODE_NVAL_GET(XROOT => XRQ_ARGUMENT, SPATH => SRQ_TAG_VALUE); + /* Дата */ + when (RES(RES.LAST).SDATA_TYPE = SDATA_TYPE_DATE) then + RES(RES.LAST).DVALUE := NODE_DVAL_GET(XROOT => XRQ_ARGUMENT, SPATH => SRQ_TAG_VALUE); + /* Текст */ + when (RES(RES.LAST).SDATA_TYPE = SDATA_TYPE_CLOB) then + RES(RES.LAST).CVALUE := NODE_CVAL_GET(XROOT => XRQ_ARGUMENT, SPATH => SRQ_TAG_VALUE); + /* Неподдерживаемый тип данных */ + else + P_EXCEPTION(0, + 'Указанный для аргумента "%s" тип данных "%s" не поддерживается (%s).', + RES(RES.LAST).SNAME, + RES(RES.LAST).SDATA_TYPE, + SRQ_ARGUMENTS_PATH || '/' || SRQ_TAG_SDATA_TYPE); + end case; + end loop; + /* Проверка обязательности */ + if ((RES.COUNT = 0) and (NREQUIRED = 1)) then + P_EXCEPTION(0, 'Не указаны аргументы (' || SRQ_ARGUMENTS_PATH || ').'); + end if; + /* Возвращаем результат */ + return RES; + end RQ_PAYLOAD_ARGUMENTS_GET; + + /* Исполнение хранимой процедуры */ + procedure EXEC_STORED + ( + XRQ_ROOT in PKG_XPATH.TNODE, -- Корневой элемент тела документа запроса + COUT out clob -- Ответ на запрос + ) + is + SRQ_STORED PKG_STD.TSTRING; -- Наименование исполняемого хранимого объекта из запроса + SRQ_RESP_ARG PKG_STD.TSTRING; -- Наименование выходного аргумента хранимого объекта из запроса для формирования тела ответа + RQ_ARGUMENTS TARGUMENTS; -- Коллекция аргументов хранимого объекта из запроса + ARGS PKG_OBJECT_DESC.TARGUMENTS; -- Коллекция формальных параметров хранимого объекта + RARG PKG_OBJECT_DESC.TARGUMENT; -- Формальный параметр хранимого объекта + ARGS_VALS PKG_CONTPRMLOC.TCONTAINER; -- Контейнер для фактических параметров хранимого объекта + RARG_VAL PKG_CONTAINER.TPARAM; -- Фактический параметр хранимого объекта + SARG_NAME PKG_STD.TSTRING; -- Наименование текущего обрабатываемого фактического параметра хранимого объекта + XRESP integer; -- Документ для ответа + XRESP_OUT_ARGUMENTS PKG_XMAKE.TNODE; -- Элемент для коллекции выходных параметров хранимого объекта + RRESP_ARGUMENT_VALUE PKG_XMAKE.TVALUE; -- Значение выходного параметра хранимого объекта + BRESP_ARG_FOUND boolean := false; -- Флаг присутствия в составе выходных аргументов аргумента с типом CLOB и именем, указанным в параметре запроса SRESP_ARG + begin + /* Создаём документ для ответа */ + XRESP := PKG_XMAKE.OPEN_CURSOR(); + /* Проверим хранимый объект в запросе */ + RQ_PAYLOAD_STORED_CHECK(XRQ_ROOT => XRQ_ROOT); + /* Считываем наименование хранимого объекта из запроса */ + SRQ_STORED := RQ_PAYLOAD_STORED_GET(XRQ_ROOT => XRQ_ROOT, NREQUIRED => 1); + /* Считываем наименование выходного аргумента хранимого объекта из запроса для формирования тела ответа */ + SRQ_RESP_ARG := NODE_SVAL_GET(XROOT => XRQ_ROOT, + SPATH => RQ_PAYLOAD_ITEM_PATH_GET(SITEM_TAG => SRQ_TAG_SRESP_ARG), + NREQUIRED => 0, + SMESSAGE_OBJECT => 'Наименование выходного аргумента для формирования тела ответа'); + /* Считаем список аргументов из запроса */ + RQ_ARGUMENTS := RQ_PAYLOAD_ARGUMENTS_GET(XRQ_ROOT => XRQ_ROOT); + /* Считываем описание параметров хранимого объекта */ + ARGS := PKG_OBJECT_DESC.DESC_ARGUMENTS(SSTORED_NAME => SRQ_STORED, BRAISE_ERROR => true); + /* Обходим входные параметры и формируем коллекцию значений */ + for I in 1 .. PKG_OBJECT_DESC.COUNT_ARGUMENTS(RARGUMENTS => ARGS) + loop + /* Считываем очередной параметр */ + RARG := PKG_OBJECT_DESC.FETCH_ARGUMENT(RARGUMENTS => ARGS, IINDEX => I); + /* Если это входной параметр */ + if (RARG.IN_OUT in (PKG_STD.PARAM_TYPE_IN, PKG_STD.PARAM_TYPE_IN_OUT)) then + /* Добавим его значение в коллекцию фактических параметров */ + case RARG.DATA_TYPE + /* Строка */ + when PKG_STD.DATA_TYPE_STR then + PKG_CONTPRMLOC.APPENDS(RCONTAINER => ARGS_VALS, + SNAME => RARG.ARGUMENT_NAME, + SVALUE => TARGUMENTS_SVAL_GET(ARGUMENTS => RQ_ARGUMENTS, + SARGUMENT => RARG.ARGUMENT_NAME), + NIN_OUT => RARG.IN_OUT); + /* Число */ + when PKG_STD.DATA_TYPE_NUM then + PKG_CONTPRMLOC.APPENDN(RCONTAINER => ARGS_VALS, + SNAME => RARG.ARGUMENT_NAME, + NVALUE => TARGUMENTS_NVAL_GET(ARGUMENTS => RQ_ARGUMENTS, + SARGUMENT => RARG.ARGUMENT_NAME), + NIN_OUT => RARG.IN_OUT); + /* Дата */ + when PKG_STD.DATA_TYPE_DATE then + PKG_CONTPRMLOC.APPENDD(RCONTAINER => ARGS_VALS, + SNAME => RARG.ARGUMENT_NAME, + DVALUE => TARGUMENTS_DVAL_GET(ARGUMENTS => RQ_ARGUMENTS, + SARGUMENT => RARG.ARGUMENT_NAME), + NIN_OUT => RARG.IN_OUT); + /* Текст */ + when PKG_STD.DATA_TYPE_CLOB then + PKG_CONTPRMLOC.APPENDLC(RCONTAINER => ARGS_VALS, + SNAME => RARG.ARGUMENT_NAME, + LCVALUE => TARGUMENTS_CVAL_GET(ARGUMENTS => RQ_ARGUMENTS, + SARGUMENT => RARG.ARGUMENT_NAME), + NIN_OUT => RARG.IN_OUT); + /* Неизвестный тип данных */ + else + P_EXCEPTION(0, + 'Тип данных (%s) входного параметра "%s" не поддерживается.', + RARG.DB_DATA_TYPE, + RARG.ARGUMENT_NAME); + end case; + end if; + end loop; + /* Исполняем процедуру */ + PKG_SQL_CALL.EXECUTE_STORED(SSTORED_NAME => SRQ_STORED, RPARAM_CONTAINER => ARGS_VALS); + /* Обходим выходные параметры и собираем их в ответ */ + SARG_NAME := PKG_CONTPRMLOC.FIRST_(RCONTAINER => ARGS_VALS); + while (SARG_NAME is not null) + loop + /* Считываем очередной параметр */ + RARG_VAL := PKG_CONTPRMLOC.GET(RCONTAINER => ARGS_VALS, SNAME => SARG_NAME); + /* Если это выходной параметр */ + if (RARG_VAL.IN_OUT in (PKG_STD.PARAM_TYPE_IN_OUT, PKG_STD.PARAM_TYPE_OUT)) then + /* Сформируем для него значение в зависимости от его типа */ + case RARG_VAL.DATA_TYPE + /* Строка */ + when PKG_STD.DATA_TYPE_STR then + RRESP_ARGUMENT_VALUE := PKG_XMAKE.VALUE(ICURSOR => XRESP, + SVALUE => PKG_CONTPRMLOC.GETS(RCONTAINER => ARGS_VALS, + SNAME => RARG_VAL.NAME)); + /* Число */ + when PKG_STD.DATA_TYPE_NUM then + RRESP_ARGUMENT_VALUE := PKG_XMAKE.VALUE(ICURSOR => XRESP, + NVALUE => PKG_CONTPRMLOC.GETN(RCONTAINER => ARGS_VALS, + SNAME => RARG_VAL.NAME)); + /* Дата */ + when PKG_STD.DATA_TYPE_DATE then + RRESP_ARGUMENT_VALUE := PKG_XMAKE.VALUE(ICURSOR => XRESP, + DVALUE => PKG_CONTPRMLOC.GETD(RCONTAINER => ARGS_VALS, + SNAME => RARG_VAL.NAME)); + /* Текст */ + when PKG_STD.DATA_TYPE_CLOB then + RRESP_ARGUMENT_VALUE := PKG_XMAKE.VALUE(ICURSOR => XRESP, + LCVALUE => PKG_CONTPRMLOC.GETLC(RCONTAINER => ARGS_VALS, + SNAME => RARG_VAL.NAME)); + if ((SRQ_RESP_ARG is not null) and (RARG_VAL.NAME = SRQ_RESP_ARG)) then + COUT := PKG_CONTPRMLOC.GETLC(RCONTAINER => ARGS_VALS, SNAME => RARG_VAL.NAME); + BRESP_ARG_FOUND := true; + exit; + end if; + /* Неизвестный тип данных */ + else + P_EXCEPTION(0, + 'Тип данных (%s) выходного параметра "%s" не поддерживается.', + RARG.DB_DATA_TYPE, + RARG.ARGUMENT_NAME); + end case; + /* Добавим ветку выходного параметра в выходную коллекцию */ + XRESP_OUT_ARGUMENTS := PKG_XMAKE.CONCAT(ICURSOR => XRESP, + RNODE00 => XRESP_OUT_ARGUMENTS, + RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => XRESP, + SNAME => SRESP_TAG_XOUT_ARGUMENTS, + RNODE00 => PKG_XMAKE.ELEMENT(ICURSOR => XRESP, + SNAME => SRESP_TAG_SNAME, + RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => XRESP, + SVALUE => RARG_VAL.NAME)), + RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => XRESP, + SNAME => SRESP_TAG_VALUE, + RVALUE00 => RRESP_ARGUMENT_VALUE), + RNODE02 => PKG_XMAKE.ELEMENT(ICURSOR => XRESP, + SNAME => SRESP_TAG_SDATA_TYPE, + RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => XRESP, + SVALUE => STD_DATA_TYPE_TO_STR(NSTD_DATA_TYPE => RARG_VAL.DATA_TYPE))))); + end if; + /* Считываем наименование следующего параметра */ + SARG_NAME := PKG_CONTPRMLOC.NEXT_(RCONTAINER => ARGS_VALS, SNAME => SARG_NAME); + end loop; + /* Проверим, что был найден опциональный аргумент для формирования полного ответа */ + if ((SRQ_RESP_ARG is not null) and (not BRESP_ARG_FOUND)) then + P_EXCEPTION(0, + 'В составе выходных параметров "%s" отсуствует аргумент "%s" типа "CLOB".', + SRQ_STORED, + SRQ_RESP_ARG); + end if; + /* Собираем ответ (только если не формировали полный ответ через аргумент для формирования полного ответа) */ + if (not BRESP_ARG_FOUND) then + COUT := PKG_XMAKE.SERIALIZE_TO_CLOB(ICURSOR => XRESP, + ITYPE => PKG_XMAKE.CONTENT_, + RNODE => PKG_XMAKE.ELEMENT(ICURSOR => XRESP, + SNAME => SRESP_TAG_XPAYLOAD, + RNODE00 => XRESP_OUT_ARGUMENTS)); + end if; + /* Очистим контейнер параметров */ + PKG_CONTPRMLOC.PURGE(RCONTAINER => ARGS_VALS); + /* Освобождаем документ результата */ + PKG_XMAKE.CLOSE_CURSOR(ICURSOR => XRESP); + exception + when others then + /* Закроем курсор и вернем ошибку */ + PKG_XMAKE.CLOSE_CURSOR(ICURSOR => XRESP); + /* Покажем ошибку */ + PKG_STATE.DIAGNOSTICS_STACKED(); + P_EXCEPTION(0, PKG_STATE.SQL_ERRM()); + end EXEC_STORED; + + /* Базовое исполнение действий */ + procedure PROCESS + ( + CIN in clob, -- Входные параметры + COUT out clob -- Результат + ) + is + XRQ_ROOT PKG_XPATH.TNODE; -- Корневой элемент тела документа запроса + SRQ_ACTION PKG_STD.TSTRING; -- Код действия из запроса + begin + PKG_TRACE.REGISTER(SDATA => 'P8PANELS', SDATA1 => CIN); + /* Разбираем запрос */ + XRQ_ROOT := RQ_ROOT_GET(CRQ => CIN); + /* Считываем код действия из запроса */ + SRQ_ACTION := RQ_ACTION_GET(XRQ_ROOT => XRQ_ROOT, NREQUIRED => 1); + /* Вызываем обработчик в зависимости от кода действия */ + case SRQ_ACTION + /* Исполнение хранимой процедуры */ + when SRQ_ACTION_EXEC_STORED then + EXEC_STORED(XRQ_ROOT => XRQ_ROOT, COUT => COUT); + /* Неизвестное действие */ + else + P_EXCEPTION(0, 'Действие "%s" не поддерживается.', SRQ_ACTION); + end case; + end PROCESS; + +end PKG_P8PANELS_BASE; +/ diff --git a/db/PKG_P8PANELS_PROJECTS.pck b/db/PKG_P8PANELS_PROJECTS.pck new file mode 100644 index 0000000..35481cf --- /dev/null +++ b/db/PKG_P8PANELS_PROJECTS.pck @@ -0,0 +1,2827 @@ +create or replace package PKG_P8PANELS_PROJECTS as + + /* Типы данных - статьи этапа проекта */ + type TSTAGE_ART is record + ( + NRN FPDARTCL.RN%type, -- Рег. номер статьи + SCODE FPDARTCL.CODE%type, -- Код статьи + SNAME FPDARTCL.NAME%type, -- Наименование статьи + NPLAN PKG_STD.TNUMBER, -- Плановое значение по статье + NCOST_FACT PKG_STD.TNUMBER, -- Фактические затраты (null - не подлежит контролю затрат) + NCOST_DIFF PKG_STD.TNUMBER, -- Отклонение по затратам (null - не подлежит контролю затрат) + NCTRL_COST PKG_STD.TNUMBER, -- Контроль затрат (null - не подлежит контролю затрат, 0 - без отклонений, 1 - есть отклонения) + NCONTR PKG_STD.TNUMBER, -- Законтрактовано (null - не подлежит контролю контрактации) + NCONTR_LEFT PKG_STD.TNUMBER, -- Остаток к контрактации (null - не подлежит контролю контрактации) + NCTRL_CONTR PKG_STD.TNUMBER -- Контроль контрактации (null - не подлежит контролю контрактации, 0 - без отклонений, 1 - есть отклонения) + ); + + /* Типы данных - коллекция статей этапа проекта */ + type TSTAGE_ARTS is table of TSTAGE_ART; + + /* Отбор проектов */ + procedure COND; + + /* Получение рег. номера документа основания (договора) проекта */ + function GET_DOC_OSN_LNK_DOCUMENT + ( + NRN in number -- Рег. номер проекта + ) return number; -- Рег. номер документа основания (договора) + + /* Подбор платежей финансирования проекта */ + procedure SELECT_FIN + ( + NRN in number, -- Рег. номер проекта + NDIRECTION in number, -- Направление (0 - приход, 1 - расход) + NIDENT out number -- Идентификатор буфера подобранных (списка отмеченных записей, null - не найдено) + ); + + /* Получение суммы входящего финансирования проекта */ + function GET_FIN_IN + ( + NRN in number -- Рег. номер проекта + ) return number; -- Сумма входящего финансирования проекта + + /* Получение суммы исходящего финансирования проекта */ + function GET_FIN_OUT + ( + NRN in number -- Рег. номер проекта + ) return number; -- Сумма исходяшего финансирования проекта + + /* Получение состояния финансирования проекта */ + function GET_CTRL_FIN + ( + NRN in number -- Рег. номер проекта + ) return number; -- Состояние (null - не определено, 0 - без отклонений, 1 - есть отклонения) + + /* Получение состояния контрактации проекта */ + function GET_CTRL_CONTR + ( + NRN in number -- Рег. номер проекта + ) return number; -- Состояние (null - не определено, 0 - без отклонений, 1 - есть отклонения) + + /* Получение состояния соисполнения проекта */ + function GET_CTRL_COEXEC + ( + NRN in number -- Рег. номер проекта + ) return number; -- Состояние (null - не определено, 0 - без отклонений, 1 - есть отклонения) + + /* Получение состояния сроков проекта */ + function GET_CTRL_PERIOD + ( + NRN in number -- Рег. номер проекта + ) return number; -- Состояние (null - не определено, 0 - без отклонений, 1 - есть отклонения) + + /* Получение состояния затрат проекта */ + function GET_CTRL_COST + ( + NRN in number -- Рег. номер проекта + ) return number; -- Состояние (null - не определено, 0 - без отклонений, 1 - есть отклонения) + + /* Получение состояния актирования проекта */ + function GET_CTRL_ACT + ( + NRN in number -- Рег. номер проекта + ) return number; -- Состояние (null - не определено, 0 - без отклонений, 1 - есть отклонения) + + /* Список проектов */ + procedure LIST + ( + 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 STAGES_COND; + + + /* Подбор платежей финансирования этапа проекта */ + procedure STAGES_SELECT_FIN + ( + NPRN in number := null, -- Рег. номер проекта (null - не отбирать по проекту) + NRN in number := null, -- Рег. номер этапа проекта (null - не отбирать по этапу) + NDIRECTION in number, -- Направление (0 - приход, 1 - расход) + NIDENT out number -- Идентификатор буфера подобранных (списка отмеченных записей, null - не найдено) + ); + + /* Получение суммы входящего финансирования этапа проекта */ + function STAGES_GET_FIN_IN + ( + NRN in number -- Рег. номер этапа проекта + ) return number; -- Сумма входящего финансирования проекта + + /* Получение суммы исходящего финансирования этапа проекта */ + function STAGES_GET_FIN_OUT + ( + NRN in number -- Рег. номер этапа проекта + ) return number; -- Сумма исходяшего финансирования проекта + + /* Получение состояния финансирования этапа проекта */ + function STAGES_GET_CTRL_FIN + ( + NRN in number -- Рег. номер этапа проекта + ) return number; -- Состояние (0 - без отклонений, 1 - есть отклонения) + + /* Получение состояния контрактации этапа проекта */ + function STAGES_GET_CTRL_CONTR + ( + NRN in number -- Рег. номер этапа проекта + ) return number; -- Состояние (null - не определено, 0 - без отклонений, 1 - есть отклонения) + + /* Получение состояния соисполнения этапа проекта */ + function STAGES_GET_CTRL_COEXEC + ( + NRN in number -- Рег. номер этапа проекта + ) return number; -- Состояние (0 - без отклонений, 1 - есть отклонения) + + /* Получение состояния сроков этапа проекта */ + function STAGES_GET_CTRL_PERIOD + ( + NRN in number -- Рег. номер этапа проекта + ) return number; -- Состояние (null - не определено, 0 - без отклонений, 1 - есть отклонения) + + /* Получение состояния затрат этапа проекта */ + function STAGES_GET_CTRL_COST + ( + NRN in number -- Рег. номер этапа проекта + ) return number; -- Состояние (null - не определено, 0 - без отклонений, 1 - есть отклонения) + + /* Получение состояния актирования этапа проекта */ + function STAGES_GET_CTRL_ACT + ( + NRN in number -- Рег. номер этапа проекта + ) return number; -- Состояние (0 - без отклонений, 1 - есть отклонения) + + /* Получение остатка срока исполнения этапа проекта */ + function STAGES_GET_DAYS_LEFT + ( + NRN in number -- Рег. номер этапа проекта + ) return number; -- Количество дней (null - не определено) + + /* Подбор записей журнала затрат этапа проекта */ + procedure STAGES_SELECT_COST_FACT + ( + NRN in number, -- Рег. номер этапа проекта (null - не отбирать по этапу) + NIDENT out number -- Идентификатор буфера подобранных (списка отмеченных записей, null - не найдено) + ); + + /* Получение суммы фактических затрат этапа проекта */ + function STAGES_GET_COST_FACT + ( + NRN in number -- Рег. номер этапа проекта + ) return number; -- Сумма фактических затрат + + /* Получение суммы реализации этапа проекта */ + function STAGES_GET_SUMM_REALIZ + ( + NRN in number, -- Рег. номер этапа проекта + NFPDARTCL_REALIZ in number -- Рег. номер статьи калькуляции для реализации + ) return number; -- Сумма реализации + + /* Список этапов */ + procedure STAGES_LIST + ( + NPRN in number, -- Рег. номер проекта + NPAGE_NUMBER in number, -- Номер страницы (игнорируется при NPAGE_SIZE=0) + NPAGE_SIZE in number, -- Количество записей на странице (0 - все) + CFILTERS in clob, -- Фильтры + CORDERS in clob, -- Сортировки + NINCLUDE_DEF in number, -- Признак включения описания колонок таблицы в ответ + COUT out clob -- Сериализованная таблица данных + ); + + /* Формирование расчетной таблицы "PM0010" - "Калькуляция этапа проекта" */ + procedure STAGES_CT_CALC; + + /* Подбор записей журнала затрат по статье калькуляции этапа проекта */ + procedure STAGE_ARTS_SELECT_COST_FACT + ( + NSTAGE in number, -- Рег. номер этапа проекта + NFPDARTCL in number := null, -- Рег. номер статьи затрат (null - по всем) + NFINFLOW_TYPE in number := null, -- Вид движения по статье (null - по всем, 0 - остаток, 1 - приход, 2 - расход) + NIDENT out number -- Идентификатор буфера подобранных (списка отмеченных записей, null - не найдено) + ); + + /* Получение суммы-факт по статье калькуляции этапа проекта */ + function STAGE_ARTS_GET_COST_FACT + ( + NSTAGE in number, -- Рег. номер этапа проекта + NFPDARTCL in number := null, -- Рег. номер статьи калькуляции (null - по всем) + NFINFLOW_TYPE in number := null -- Вид движения по статье (null - по всем, 0 - остаток, 1 - приход, 2 - расход) + ) return number; -- Сумма-факт по статье + + /* Подбор записей договоров с соисполнителями по статье калькуляции этапа проекта */ + procedure STAGE_ARTS_SELECT_CONTR + ( + NSTAGE in number, -- Рег. номер этапа проекта + NFPDARTCL in number := null, -- Рег. номер статьи затрат (null - по всем) + NIDENT out number -- Идентификатор буфера подобранных (списка отмеченных записей, null - не найдено) + ); + + /* Получение списка статей этапа проекта */ + procedure STAGE_ARTS_GET + ( + NSTAGE in number, -- Рег. номер этапа проекта + NINC_COST in number := 0, -- Включить сведения о затратах (0 - нет, 1 - да) + NINC_CONTR in number := 0, -- Включить сведения о контрактации (0 - нет, 1 - да) + RSTAGE_ARTS out TSTAGE_ARTS -- Список статей этапа проекта + ); + + /* Список статей калькуляции этапа проекта */ + procedure STAGE_ARTS_LIST + ( + NSTAGE in number, -- Рег. номер этапа проекта + CFILTERS in clob, -- Фильтры + NINCLUDE_DEF in number, -- Признак включения описания колонок таблицы в ответ + COUT out clob -- Сериализованная таблица данных + ); + + /* Список договоров этапа проекта */ + procedure STAGE_CONTRACTS_COND; + + /* Список договоров этапа проекта */ + procedure STAGE_CONTRACTS_LIST + ( + NSTAGE in number, -- Рег. номер этапа проекта + NPAGE_NUMBER in number, -- Номер страницы (игнорируется при NPAGE_SIZE=0) + NPAGE_SIZE in number, -- Количество записей на странице (0 - все) + CFILTERS in clob, -- Фильтры + CORDERS in clob, -- Сортировки + NINCLUDE_DEF in number, -- Признак включения описания колонок таблицы в ответ + COUT out clob -- Сериализованная таблица данных + ); + +end PKG_P8PANELS_PROJECTS; +/ +create or replace package body PKG_P8PANELS_PROJECTS as + +/* +TODO: owner="root" created="20.09.2023" +text="ПРАВА ДОСТУПА!!!!" +*/ + /* Константы - предопределённые значения */ + SYES constant PKG_STD.TSTRING := 'Да'; -- Да + NDAYS_LEFT_LIMIT constant PKG_STD.TNUMBER := 30; -- Лимит отстатка дней для контроля сроков + SFPDARTCL_REALIZ constant PKG_STD.TSTRING := '14 Цена без НДС'; -- Мнемокод статьи калькуляции для учёта реализации + + /* Константы - листы расчётной таблицы "PM0010" - "Калькуляция этапа проекта" */ + SSTAGES_CT_CALC_SH_CACL constant PKG_STD.TSTRING := 'Калькуляция'; -- Лист "Калькуляция" + + /* Константы - таблицы расчётной таблицы "PM0010" - "Калькуляция этапа проекта" */ + SSTAGES_CT_CALC_TBL_CLARTS constant PKG_STD.TSTRING := 'СтатьиКалькуляции'; -- Таблица "Статьи калькуляции" + + /* Константы - строки расчётной таблицы "PM0010" - "Калькуляция этапа проекта" */ + SSTAGES_CT_CALC_LN_ARTS constant PKG_STD.TSTRING := 'Статьи'; -- Строка "Статьи" + + /* Константы - колонки расчётной таблицы "PM0010" - "Калькуляция этапа проекта" */ + SSTAGES_CT_CALC_CL_NUMB constant PKG_STD.TSTRING := 'Номер'; -- Колонка "Номер" + SSTAGES_CT_CALC_CL_NAME constant PKG_STD.TSTRING := 'Наименование'; -- Колонка "Наименование статьи" + SSTAGES_CT_CALC_CL_SUMM_PL constant PKG_STD.TSTRING := 'ПлановаяСумма'; -- Колонка "Плановая сумма" + + /* Константы - параметры расчётной таблицы "PM0010" - "Калькуляция этапа проекта" */ + SSTAGES_CT_CALC_PRM_COMP constant PKG_STD.TSTRING := 'PM0010_Организация'; -- Параметр "Организация" + SSTAGES_CT_CALC_PRM_PRJ constant PKG_STD.TSTRING := 'PM0010_КодПроекта'; -- Параметр "Код проекта" + SSTAGES_CT_CALC_PRM_STG constant PKG_STD.TSTRING := 'PM0010_НомерЭтапаПроекта'; -- Параметр "Номер этапа проекта" + SSTAGES_CT_CALC_PRM_ARTSCAT constant PKG_STD.TSTRING := 'PM0010_КатСтатКальк'; -- Параметр "Каталог статей калькуляции" + + /* Считывание записи проекта */ + function GET + ( + NRN in number -- Рег. номер проекта + ) return PROJECT%rowtype -- Запись проекта + is + RRES PROJECT%rowtype; -- Буфер для результата + begin + select P.* into RRES from PROJECT P where P.RN = NRN; + return RRES; + exception + when NO_DATA_FOUND then + PKG_MSG.RECORD_NOT_FOUND(NFLAG_SMART => 0, NDOCUMENT => NRN, SUNIT_TABLE => 'PROJECT'); + end GET; + + /* Отбор проектов */ + procedure COND + as + begin + /* Установка главной таблицы */ + PKG_COND_BROKER.SET_TABLE(STABLE_NAME => 'PROJECT'); + /* Тип проекта */ + PKG_COND_BROKER.ADD_CONDITION_CODE(SCOLUMN_NAME => 'CODE', + SCONDITION_NAME => 'EDPROJECTTYPE', + SJOINS => 'PRJTYPE <- RN;PRJTYPE'); + /* Мнемокод */ + PKG_COND_BROKER.ADD_CONDITION_CODE(SCOLUMN_NAME => 'CODE', SCONDITION_NAME => 'EDMNEMO'); + /* Наименование */ + PKG_COND_BROKER.ADD_CONDITION_CODE(SCOLUMN_NAME => 'NAME', SCONDITION_NAME => 'EDNAME'); + /* Услованое наименование */ + PKG_COND_BROKER.ADD_CONDITION_CODE(SCOLUMN_NAME => 'NAME_USL', SCONDITION_NAME => 'EDNAME_USL'); + /* Дата начала план */ + PKG_COND_BROKER.ADD_CONDITION_BETWEEN(SCOLUMN_NAME => 'BEGPLAN', + SCONDITION_NAME_FROM => 'EDPLANBEGFrom', + SCONDITION_NAME_TO => 'EDPLANBEGTo'); + /* Дата окончания план */ + PKG_COND_BROKER.ADD_CONDITION_BETWEEN(SCOLUMN_NAME => 'ENDPLAN', + SCONDITION_NAME_FROM => 'EDPLANENDFrom', + SCONDITION_NAME_TO => 'EDPLANENDTo'); + /* Состояние */ + PKG_COND_BROKER.ADD_CONDITION_ENUM(SCOLUMN_NAME => 'STATE', SCONDITION_NAME => 'CGSTATE'); + /* Заказчик */ + PKG_COND_BROKER.ADD_CONDITION_CODE(SCOLUMN_NAME => 'AGNABBR', + SCONDITION_NAME => 'EDEXT_CUST', + SJOINS => 'EXT_CUST <- RN;AGNLIST'); + /* Контроль финансирования */ + if (PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'EDCTRL_FIN') = 1) then + PKG_COND_BROKER.ADD_CLAUSE(SCLAUSE => 'PKG_P8PANELS_PROJECTS.GET_CTRL_FIN(RN) = :EDCTRL_FIN'); + PKG_COND_BROKER.BIND_VARIABLE(SVARIABLE_NAME => 'EDCTRL_FIN', + NVALUE => PKG_COND_BROKER.GET_CONDITION_NUM(SCONDITION_NAME => 'EDCTRL_FIN')); + end if; + /* Контроль контрактации */ + if (PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'EDCTRL_CONTR') = 1) then + PKG_COND_BROKER.ADD_CLAUSE(SCLAUSE => 'PKG_P8PANELS_PROJECTS.GET_CTRL_CONTR(RN) = :EDCTRL_CONTR'); + PKG_COND_BROKER.BIND_VARIABLE(SVARIABLE_NAME => 'EDCTRL_CONTR', + NVALUE => PKG_COND_BROKER.GET_CONDITION_NUM(SCONDITION_NAME => 'EDCTRL_CONTR')); + end if; + /* Контроль соисполнения */ + if (PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'EDCTRL_COEXEC') = 1) then + PKG_COND_BROKER.ADD_CLAUSE(SCLAUSE => 'PKG_P8PANELS_PROJECTS.GET_CTRL_COEXEC(RN) = :EDCTRL_COEXEC'); + PKG_COND_BROKER.BIND_VARIABLE(SVARIABLE_NAME => 'EDCTRL_COEXEC', + NVALUE => PKG_COND_BROKER.GET_CONDITION_NUM(SCONDITION_NAME => 'EDCTRL_COEXEC')); + end if; + /* Контроль сроков */ + if (PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'EDCTRL_PERIOD') = 1) then + PKG_COND_BROKER.ADD_CLAUSE(SCLAUSE => 'PKG_P8PANELS_PROJECTS.GET_CTRL_PERIOD(RN) = :EDCTRL_PERIOD'); + PKG_COND_BROKER.BIND_VARIABLE(SVARIABLE_NAME => 'EDCTRL_PERIOD', + NVALUE => PKG_COND_BROKER.GET_CONDITION_NUM(SCONDITION_NAME => 'EDCTRL_PERIOD')); + end if; + /* Контроль затрат */ + if (PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'EDCTRL_COST') = 1) then + PKG_COND_BROKER.ADD_CLAUSE(SCLAUSE => 'PKG_P8PANELS_PROJECTS.GET_CTRL_COST(RN) = :EDCTRL_COST'); + PKG_COND_BROKER.BIND_VARIABLE(SVARIABLE_NAME => 'EDCTRL_COST', + NVALUE => PKG_COND_BROKER.GET_CONDITION_NUM(SCONDITION_NAME => 'EDCTRL_COST')); + end if; + /* Контроль актирования */ + if (PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'EDCTRL_ACT') = 1) then + PKG_COND_BROKER.ADD_CLAUSE(SCLAUSE => 'PKG_P8PANELS_PROJECTS.GET_CTRL_ACT(RN) = :EDCTRL_ACT'); + PKG_COND_BROKER.BIND_VARIABLE(SVARIABLE_NAME => 'EDCTRL_ACT', + NVALUE => PKG_COND_BROKER.GET_CONDITION_NUM(SCONDITION_NAME => 'EDCTRL_ACT')); + end if; + end COND; + + /* Получение рег. номера документа основания (договора) проекта */ + function GET_DOC_OSN_LNK_DOCUMENT + ( + NRN in number -- Рег. номер проекта + ) return number -- Рег. номер документа основания (договора) + is + begin + /* Подберём договор с заказчиком по ЛС этапа проекта */ + for C in (select CN.RN + from PROJECTSTAGE PS, + STAGES S, + CONTRACTS CN + where PS.PRN = NRN + and PS.FACEACCCUST = S.FACEACC + and S.PRN = CN.RN + group by CN.RN) + loop + /* Вернём первый найденный */ + return C.RN; + end loop; + /* Ничего не нашли */ + return null; + end GET_DOC_OSN_LNK_DOCUMENT; + + /* Подбор платежей финансирования проекта */ + procedure SELECT_FIN + ( + NRN in number, -- Рег. номер проекта + NDIRECTION in number, -- Направление (0 - приход, 1 - расход) + NIDENT out number -- Идентификатор буфера подобранных (списка отмеченных записей, null - не найдено) + ) + is + begin + /* Подберём платежи */ + STAGES_SELECT_FIN(NPRN => NRN, NDIRECTION => NDIRECTION, NIDENT => NIDENT); + end SELECT_FIN; + + /* Получение суммы входящего финансирования проекта */ + function GET_FIN_IN + ( + NRN in number -- Рег. номер проекта + ) return number -- Сумма входящего финансирования проекта + is + NRES PKG_STD.TNUMBER := 0; -- Буфер для результата + begin + /* Обходим этапы и считаем */ + for C in (select PS.RN from PROJECTSTAGE PS where PS.PRN = NRN) + loop + NRES := NRES + STAGES_GET_FIN_IN(NRN => C.RN); + end loop; + /* Возвращаем результат */ + return NRES; + end GET_FIN_IN; + + /* Получение суммы исходящего финансирования проекта */ + function GET_FIN_OUT + ( + NRN in number -- Рег. номер проекта + ) return number -- Сумма исходяшего финансирования проекта + is + NRES PKG_STD.TNUMBER := 0; -- Буфер для результата + begin + /* Обходим этапы и считаем */ + for C in (select PS.RN from PROJECTSTAGE PS where PS.PRN = NRN) + loop + NRES := NRES + STAGES_GET_FIN_OUT(NRN => C.RN); + end loop; + /* Возвращаем результат */ + return NRES; + end GET_FIN_OUT; + + /* Получение состояния финансирования проекта */ + function GET_CTRL_FIN + ( + NRN in number -- Рег. номер проекта + ) return number -- Состояние (null - не определено, 0 - без отклонений, 1 - есть отклонения) + is + BFOUND boolean := false; -- Флаг наличия этапов + begin + /* Обходим этапы */ + for C in (select PS.RN from PROJECTSTAGE PS where PS.PRN = NRN) + loop + /* Выставим флаг наличия этапов */ + BFOUND := true; + /* Если у этапа есть отклонение - оно есть и у проекта */ + if (STAGES_GET_CTRL_FIN(NRN => C.RN) = 1) then + return 1; + end if; + end loop; + /* Если мы здесь - отклонений нет */ + if (BFOUND) then + return 0; + else + return null; + end if; + end GET_CTRL_FIN; + + /* Получение состояния контрактации проекта */ + function GET_CTRL_CONTR + ( + NRN in number -- Рег. номер проекта + ) return number -- Состояние (null - не определено, 0 - без отклонений, 1 - есть отклонения) + is + NSTAGE_CTRL PKG_STD.TNUMBER; -- Состояние этапа + NCNT_STAGES PKG_STD.TNUMBER :=0; -- Количество этапов + NCNT_NULL PKG_STD.TNUMBER :=0; -- Количество "безконтрольных" этапов + begin + /* Обходим этапы */ + for C in (select PS.RN from PROJECTSTAGE PS where PS.PRN = NRN) + loop + /* Увеличим счётчик этапов */ + NCNT_STAGES := NCNT_STAGES + 1; + /* Получим состояние этапа */ + NSTAGE_CTRL := STAGES_GET_CTRL_CONTR(NRN => C.RN); + /* Подсчитаем количество "безконтрольных" */ + if (NSTAGE_CTRL is null) then + NCNT_NULL := NCNT_NULL + 1; + end if; + /* Если у этапа есть отклонение - оно есть и у проекта */ + if (NSTAGE_CTRL = 1) then + return 1; + end if; + end loop; + /* Если ни один этап не подлежит контролю - то и состояние проекта тоже */ + if (NCNT_NULL = NCNT_STAGES) then + return null; + end if; + /* Если мы здесь - отклонений нет */ + if (NCNT_STAGES > 0) then + return 0; + else + /* Нет этапов и нет контроля */ + return null; + end if; + end GET_CTRL_CONTR; + + /* Получение состояния соисполнения проекта */ + function GET_CTRL_COEXEC + ( + NRN in number -- Рег. номер проекта + ) return number -- Состояние (null - не определено, 0 - без отклонений, 1 - есть отклонения) + is + BFOUND boolean := false; -- Флаг наличия этапов + begin + /* Обходим этапы */ + for C in (select PS.RN from PROJECTSTAGE PS where PS.PRN = NRN) + loop + /* Выставим флаг наличия этапов */ + BFOUND := true; + /* Если у этапа есть отклонение - оно есть и у проекта */ + if (STAGES_GET_CTRL_COEXEC(NRN => C.RN) = 1) then + return 1; + end if; + end loop; + /* Если мы здесь - отклонений нет */ + if (BFOUND) then + return 0; + else + return null; + end if; + end GET_CTRL_COEXEC; + + /* Получение состояния сроков проекта */ + function GET_CTRL_PERIOD + ( + NRN in number -- Рег. номер проекта + ) return number -- Состояние (null - не определено, 0 - без отклонений, 1 - есть отклонения) + is + NSTAGE_CTRL PKG_STD.TNUMBER; -- Состояние этапа + NCNT_STAGES PKG_STD.TNUMBER :=0; -- Количество этапов + NCNT_NULL PKG_STD.TNUMBER :=0; -- Количество "безконтрольных" этапов + begin + /* Обходим этапы */ + for C in (select PS.RN from PROJECTSTAGE PS where PS.PRN = NRN) + loop + /* Увеличим счётчик этапов */ + NCNT_STAGES := NCNT_STAGES + 1; + /* Получим состояние этапа */ + NSTAGE_CTRL := STAGES_GET_CTRL_PERIOD(NRN => C.RN); + /* Подсчитаем количество "безконтрольных" */ + if (NSTAGE_CTRL is null) then + NCNT_NULL := NCNT_NULL + 1; + end if; + /* Если у этапа есть отклонение - оно есть и у проекта */ + if (NSTAGE_CTRL = 1) then + return 1; + end if; + end loop; + /* Если ни один этап не подлежит контролю - то и состояние проекта тоже */ + if (NCNT_NULL = NCNT_STAGES) then + return null; + end if; + /* Если мы здесь - отклонений нет */ + if (NCNT_STAGES > 0) then + return 0; + else + /* Нет этапов и нет контроля */ + return null; + end if; + end GET_CTRL_PERIOD; + + /* Получение состояния затрат проекта */ + function GET_CTRL_COST + ( + NRN in number -- Рег. номер проекта + ) return number -- Состояние (null - не определено, 0 - без отклонений, 1 - есть отклонения) + is + NSTAGE_CTRL PKG_STD.TNUMBER; -- Состояние этапа + NCNT_STAGES PKG_STD.TNUMBER :=0; -- Количество этапов + NCNT_NULL PKG_STD.TNUMBER :=0; -- Количество "безконтрольных" этапов + begin + /* Обходим этапы */ + for C in (select PS.RN from PROJECTSTAGE PS where PS.PRN = NRN) + loop + /* Увеличим счётчик этапов */ + NCNT_STAGES := NCNT_STAGES + 1; + /* Получим состояние этапа */ + NSTAGE_CTRL := STAGES_GET_CTRL_COST(NRN => C.RN); + /* Подсчитаем количество "безконтрольных" */ + if (NSTAGE_CTRL is null) then + NCNT_NULL := NCNT_NULL + 1; + end if; + /* Если у этапа есть отклонение - оно есть и у проекта */ + if (NSTAGE_CTRL = 1) then + return 1; + end if; + end loop; + /* Если ни один этап не подлежит контролю - то и состояние проекта тоже */ + if (NCNT_NULL = NCNT_STAGES) then + return null; + end if; + /* Если мы здесь - отклонений нет */ + if (NCNT_STAGES > 0) then + return 0; + else + /* Нет этапов и нет контроля */ + return null; + end if; + end GET_CTRL_COST; + + /* Получение состояния актирования проекта */ + function GET_CTRL_ACT + ( + NRN in number -- Рег. номер проекта + ) return number -- Состояние (null - не определено, 0 - без отклонений, 1 - есть отклонения) + is + BFOUND boolean := false; -- Флаг наличия этапов + begin + /* Обходим этапы */ + for C in (select PS.RN from PROJECTSTAGE PS where PS.PRN = NRN) + loop + /* Выставим флаг наличия этапов */ + BFOUND := true; + /* Если у этапа есть отклонение - оно есть и у проекта */ + if (STAGES_GET_CTRL_ACT(NRN => C.RN) = 1) then + return 1; + end if; + end loop; + /* Если мы здесь - отклонений нет */ + if (BFOUND) then + return 0; + else + return null; + end if; + end GET_CTRL_ACT; + + /* Список проектов */ + procedure LIST + ( + 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.TFILTERS; -- Фильтры + RO PKG_P8PANELS_VISUAL.TORDERS; -- Сортировки + RDG PKG_P8PANELS_VISUAL.TDATA_GRID; -- Описание таблицы + RDG_ROW PKG_P8PANELS_VISUAL.TROW; -- Строка таблицы + RCOL_VALS PKG_P8PANELS_VISUAL.TCOL_VALS; -- Предопределённые значения столбцов + NROW_FROM PKG_STD.TREF; -- Номер строки с + NROW_TO PKG_STD.TREF; -- Номер строки по + CSQL clob; -- Буфер для запроса + ICURSOR integer; -- Курсор для исполнения запроса + NECON_RESP_DP PKG_STD.TREF; -- Рег. номер ДС "Ответственный экономист" + begin + /* Читаем фильтры */ + RF := PKG_P8PANELS_VISUAL.TFILTERS_FROM_XML(CFILTERS => CFILTERS); + /* Читем сортировки */ + RO := PKG_P8PANELS_VISUAL.TORDERS_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.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 => 'SCODE', + SCAPTION => 'Код', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + SCOND_FROM => 'EDMNEMO', + BORDER => true, + BFILTER => true); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'SNAME', + SCAPTION => 'Наименование', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + SCOND_FROM => 'EDNAME', + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'SNAME_USL', + SCAPTION => 'Условное наименование', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + SCOND_FROM => 'EDNAME_USL', + BORDER => true, + BFILTER => true); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'SEXPECTED_RES', + SCAPTION => 'Ожидаемые результаты', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'SPRJTYPE', + SCAPTION => 'Тип', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + SCOND_FROM => 'EDPROJECTTYPE', + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'SEXT_CUST', + SCAPTION => 'Заказчик', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + SCOND_FROM => 'EDEXT_CUST', + BORDER => true, + BFILTER => true); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'SGOVCNTRID', + SCAPTION => 'ИГК', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'SDOC_OSN', + SCAPTION => 'Документ-основание', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'SLNK_UNIT_SDOC_OSN', + SCAPTION => 'Документ-основание (код раздела ссылки)', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NLNK_DOCUMENT_SDOC_OSN', + SCAPTION => 'Документ-основание (документ ссылки)', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'SSUBDIV_RESP', + SCAPTION => 'Подразделение-исполнитель', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'SRESPONSIBLE', + SCAPTION => 'Ответственный исполнитель', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'SECON_RESP', + SCAPTION => 'Ответственный экономист', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 0, BCLEAR => true); + PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 1); + PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 2); + PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 3); + PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 4); + PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 5); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NSTATE', + SCAPTION => 'Состояние', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, + SCOND_FROM => 'CGSTATE', + BORDER => true, + BFILTER => true, + RCOL_VALS => RCOL_VALS); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'DBEGPLAN', + SCAPTION => 'Дата начала', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_DATE, + SCOND_FROM => 'EDPLANBEGFrom', + SCOND_TO => 'EDPLANBEGTo', + BORDER => true, + BFILTER => true); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'DENDPLAN', + SCAPTION => 'Дата окончания', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_DATE, + SCOND_FROM => 'EDPLANENDFrom', + SCOND_TO => 'EDPLANENDTo', + BORDER => true, + BFILTER => true); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NCOST_SUM', + SCAPTION => 'Стоимость', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'SCURNAMES', + SCAPTION => 'Валюта', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NFIN_IN', + SCAPTION => 'Входящее финансирование', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'SLNK_UNIT_NFIN_IN', + SCAPTION => 'Входящее финансирование (код раздела ссылки)', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NLNK_DOCUMENT_NFIN_IN', + SCAPTION => 'Входящее финансирование (документ ссылки)', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NFIN_OUT', + SCAPTION => 'Исходящее финансирование', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'SLNK_UNIT_NFIN_OUT', + SCAPTION => 'Исходящее финансирование (код раздела ссылки)', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NLNK_DOCUMENT_NFIN_OUT', + SCAPTION => 'Исходящее финансирование (документ ссылки)', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 0, BCLEAR => true); + PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 1); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NCTRL_FIN', + SCAPTION => 'Финансирование', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, + SCOND_FROM => 'EDCTRL_FIN', + BORDER => true, + BFILTER => true, + RCOL_VALS => RCOL_VALS); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NCTRL_CONTR', + SCAPTION => 'Контрактация', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, + SCOND_FROM => 'EDCTRL_CONTR', + BORDER => true, + BFILTER => true, + RCOL_VALS => RCOL_VALS); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NCTRL_COEXEC', + SCAPTION => 'Соисполнители', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, + SCOND_FROM => 'EDCTRL_COEXEC', + BORDER => true, + BFILTER => true, + RCOL_VALS => RCOL_VALS); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NCTRL_PERIOD', + SCAPTION => 'Сроки', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, + SCOND_FROM => 'EDCTRL_PERIOD', + BORDER => true, + BFILTER => true, + RCOL_VALS => RCOL_VALS); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NCTRL_COST', + SCAPTION => 'Затраты', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, + SCOND_FROM => 'EDCTRL_COST', + BORDER => true, + BFILTER => true, + RCOL_VALS => RCOL_VALS); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NCTRL_ACT', + SCAPTION => 'Актирование', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, + SCOND_FROM => 'EDCTRL_ACT', + BORDER => true, + BFILTER => true, + RCOL_VALS => RCOL_VALS); + /* Определим дополнительные свойства - ответственный экономист */ + FIND_DOCS_PROPS_CODE(NFLAG_SMART => 1, NCOMPANY => NCOMPANY, SCODE => 'ПУП.SECON_RESP', NRN => NECON_RESP_DP); + /* Обходим данные */ + begin + /* Собираем запрос */ + CSQL := 'select * + from (select D.*, + ROWNUM NROW + from (select P.RN NRN, + P.CODE SCODE, + P.NAME SNAME, + P.NAME_USL SNAME_USL, + P.EXPECTED_RES SEXPECTED_RES, + PT.CODE SPRJTYPE, + EC.AGNABBR SEXT_CUST, + ''"'' || GC.CODE || ''"'' SGOVCNTRID, + P.DOC_OSN SDOC_OSN, + ''Contracts'' SLNK_UNIT_SDOC_OSN, + PKG_P8PANELS_PROJECTS.GET_DOC_OSN_LNK_DOCUMENT(P.RN) NLNK_DOCUMENT_SDOC_OSN, + SR.CODE SSUBDIV_RESP, + R.AGNABBR SRESPONSIBLE, + F_DOCS_PROPS_GET_STR_VALUE(:NECON_RESP_DP, ''Projects'', P.RN) SECON_RESP, + P.STATE NSTATE, + P.BEGPLAN DBEGPLAN, + P.ENDPLAN DENDPLAN, + P.COST_SUM_BASECURR NCOST_SUM, + CN.INTCODE SCURNAMES, + PKG_P8PANELS_PROJECTS.GET_FIN_IN(P.RN) NFIN_IN, + ''Paynotes'' SLNK_UNIT_NFIN_IN, + 0 NLNK_DOCUMENT_NFIN_IN, + PKG_P8PANELS_PROJECTS.GET_FIN_OUT(P.RN) NFIN_OUT, + ''Paynotes'' SLNK_UNIT_NFIN_OUT, + 1 NLNK_DOCUMENT_NFIN_OUT, + PKG_P8PANELS_PROJECTS.GET_CTRL_FIN(P.RN) NCTRL_FIN, + PKG_P8PANELS_PROJECTS.GET_CTRL_CONTR(P.RN) NCTRL_CONTR, + PKG_P8PANELS_PROJECTS.GET_CTRL_COEXEC(P.RN) NCTRL_COEXEC, + PKG_P8PANELS_PROJECTS.GET_CTRL_PERIOD(P.RN) NCTRL_PERIOD, + PKG_P8PANELS_PROJECTS.GET_CTRL_COST(P.RN) NCTRL_COST, + PKG_P8PANELS_PROJECTS.GET_CTRL_ACT(P.RN) NCTRL_ACT + from PROJECT P, + PRJTYPE PT, + AGNLIST EC, + GOVCNTRID GC, + INS_DEPARTMENT SR, + AGNLIST R, + CURNAMES CN + where P.PRJTYPE = PT.RN + and P.EXT_CUST = EC.RN(+) + and P.GOVCNTRID = GC.RN(+) + and P.SUBDIV_RESP = SR.RN(+) + and P.RESPONSIBLE = R.RN(+) + and P.CURNAMES = CN.RN + and P.RN in (select ID from COND_BROKER_IDSMART where IDENT = :NIDENT) %ORDER_BY%) D) F + where F.NROW between :NROW_FROM and :NROW_TO'; + /* Учтём сортировки */ + PKG_P8PANELS_VISUAL.TORDERS_SET_QUERY(RDATA_GRID => RDG, RORDERS => RO, SPATTERN => '%ORDER_BY%', CSQL => CSQL); + /* Учтём фильтры */ + PKG_P8PANELS_VISUAL.TFILTERS_SET_QUERY(NIDENT => NIDENT, + NCOMPANY => NCOMPANY, + SUNIT => 'Projects', + SPROCEDURE => 'PKG_P8PANELS_PROJECTS.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 => 'NECON_RESP_DP', NVALUE => NECON_RESP_DP); + PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NIDENT', NVALUE => NIDENT); + PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NROW_FROM', NVALUE => NROW_FROM); + PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NROW_TO', NVALUE => NROW_TO); + /* Описываем структуру записи курсора */ + PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 1); + PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 2); + PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 3); + PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 4); + PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 5); + PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 6); + PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 7); + PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 8); + PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 9); + PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 10); + PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 11); + PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 12); + PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 13); + PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 14); + PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 15); + PKG_SQL_DML.DEFINE_COLUMN_DATE(ICURSOR => ICURSOR, IPOSITION => 16); + PKG_SQL_DML.DEFINE_COLUMN_DATE(ICURSOR => ICURSOR, IPOSITION => 17); + PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 18); + PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 19); + PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 20); + PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 21); + PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 22); + PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 23); + PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 24); + PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 25); + PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 26); + PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 27); + PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 28); + PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 29); + PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 30); + PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 31); + /* Делаем выборку */ + if (PKG_SQL_DML.EXECUTE(ICURSOR => ICURSOR) = 0) then + null; + end if; + /* Обходим выбранные записи */ + while (PKG_SQL_DML.FETCH_ROWS(ICURSOR => ICURSOR) > 0) + loop + /* Добавляем колонки с данными */ + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NRN', ICURSOR => ICURSOR, NPOSITION => 1, BCLEAR => true); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SCODE', ICURSOR => ICURSOR, NPOSITION => 2); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SNAME', ICURSOR => ICURSOR, NPOSITION => 3); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, + SNAME => 'SNAME_USL', + ICURSOR => ICURSOR, + NPOSITION => 4); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, + SNAME => 'SEXPECTED_RES', + ICURSOR => ICURSOR, + NPOSITION => 5); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SPRJTYPE', ICURSOR => ICURSOR, NPOSITION => 6); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, + SNAME => 'SEXT_CUST', + ICURSOR => ICURSOR, + NPOSITION => 7); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, + SNAME => 'SGOVCNTRID', + ICURSOR => ICURSOR, + NPOSITION => 8); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SDOC_OSN', ICURSOR => ICURSOR, NPOSITION => 9); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, + SNAME => 'SLNK_UNIT_SDOC_OSN', + ICURSOR => ICURSOR, + NPOSITION => 10); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, + SNAME => 'NLNK_DOCUMENT_SDOC_OSN', + ICURSOR => ICURSOR, + NPOSITION => 11); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, + SNAME => 'SSUBDIV_RESP', + ICURSOR => ICURSOR, + NPOSITION => 12); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, + SNAME => 'SRESPONSIBLE', + ICURSOR => ICURSOR, + NPOSITION => 13); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, + SNAME => 'SECON_RESP', + ICURSOR => ICURSOR, + NPOSITION => 14); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NSTATE', ICURSOR => ICURSOR, NPOSITION => 15); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLD(RROW => RDG_ROW, + SNAME => 'DBEGPLAN', + ICURSOR => ICURSOR, + NPOSITION => 16); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLD(RROW => RDG_ROW, + SNAME => 'DENDPLAN', + ICURSOR => ICURSOR, + NPOSITION => 17); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, + SNAME => 'NCOST_SUM', + ICURSOR => ICURSOR, + NPOSITION => 18); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, + SNAME => 'SCURNAMES', + ICURSOR => ICURSOR, + NPOSITION => 19); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NFIN_IN', ICURSOR => ICURSOR, NPOSITION => 20); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, + SNAME => 'SLNK_UNIT_NFIN_IN', + ICURSOR => ICURSOR, + NPOSITION => 21); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, + SNAME => 'NLNK_DOCUMENT_NFIN_IN', + ICURSOR => ICURSOR, + NPOSITION => 22); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, + SNAME => 'NFIN_OUT', + ICURSOR => ICURSOR, + NPOSITION => 23); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, + SNAME => 'SLNK_UNIT_NFIN_OUT', + ICURSOR => ICURSOR, + NPOSITION => 24); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, + SNAME => 'NLNK_DOCUMENT_NFIN_OUT', + ICURSOR => ICURSOR, + NPOSITION => 25); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, + SNAME => 'NCTRL_FIN', + ICURSOR => ICURSOR, + NPOSITION => 26); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, + SNAME => 'NCTRL_CONTR', + ICURSOR => ICURSOR, + NPOSITION => 27); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, + SNAME => 'NCTRL_COEXEC', + ICURSOR => ICURSOR, + NPOSITION => 28); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, + SNAME => 'NCTRL_PERIOD', + ICURSOR => ICURSOR, + NPOSITION => 29); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, + SNAME => 'NCTRL_COST', + ICURSOR => ICURSOR, + NPOSITION => 30); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, + SNAME => 'NCTRL_ACT', + ICURSOR => ICURSOR, + NPOSITION => 31); + /* Добавляем строку в таблицу */ + PKG_P8PANELS_VISUAL.TDATA_GRID_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.TDATA_GRID_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => NINCLUDE_DEF); + end LIST; + + /* Считывание записи этапа проекта */ + function STAGES_GET + ( + NRN in number -- Рег. номер этапа проекта + ) return PROJECTSTAGE%rowtype -- Запись этапа проекта + is + RRES PROJECTSTAGE%rowtype; -- Буфер для результата + begin + select PS.* into RRES from PROJECTSTAGE PS where PS.RN = NRN; + return RRES; + exception + when NO_DATA_FOUND then + PKG_MSG.RECORD_NOT_FOUND(NFLAG_SMART => 0, NDOCUMENT => NRN, SUNIT_TABLE => 'PROJECTSTAGE'); + end STAGES_GET; + + /* Отбор этапов проектов */ + procedure STAGES_COND + as + begin + /* Установка главной таблицы */ + PKG_COND_BROKER.SET_TABLE(STABLE_NAME => 'PROJECTSTAGE'); + /* Проект */ + PKG_COND_BROKER.SET_COLUMN_PRN(SCOLUMN_NAME => 'PRN'); + /* Номер */ + PKG_COND_BROKER.ADD_CONDITION_CODE(SCOLUMN_NAME => 'NUMB', SCONDITION_NAME => 'EDNUMB'); + /* Наименование */ + PKG_COND_BROKER.ADD_CONDITION_CODE(SCOLUMN_NAME => 'NAME', SCONDITION_NAME => 'EDNAME'); + /* Дата начала план */ + PKG_COND_BROKER.ADD_CONDITION_BETWEEN(SCOLUMN_NAME => 'BEGPLAN', + SCONDITION_NAME_FROM => 'EDPLANBEGFrom', + SCONDITION_NAME_TO => 'EDPLANBEGTo'); + /* Дата окончания план */ + PKG_COND_BROKER.ADD_CONDITION_BETWEEN(SCOLUMN_NAME => 'ENDPLAN', + SCONDITION_NAME_FROM => 'EDPLANENDFrom', + SCONDITION_NAME_TO => 'EDPLANENDTo'); + /* Состояние */ + PKG_COND_BROKER.ADD_CONDITION_ENUM(SCOLUMN_NAME => 'STATE', SCONDITION_NAME => 'CGSTATE'); + /* Контроль финансирования */ + if (PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'EDCTRL_FIN') = 1) then + PKG_COND_BROKER.ADD_CLAUSE(SCLAUSE => 'PKG_P8PANELS_PROJECTS.STAGES_GET_CTRL_FIN(RN) = :EDCTRL_FIN'); + PKG_COND_BROKER.BIND_VARIABLE(SVARIABLE_NAME => 'EDCTRL_FIN', + NVALUE => PKG_COND_BROKER.GET_CONDITION_NUM(SCONDITION_NAME => 'EDCTRL_FIN')); + end if; + /* Контроль контрактации */ + if (PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'EDCTRL_CONTR') = 1) then + PKG_COND_BROKER.ADD_CLAUSE(SCLAUSE => 'PKG_P8PANELS_PROJECTS.STAGES_GET_CTRL_CONTR(RN) = :EDCTRL_CONTR'); + PKG_COND_BROKER.BIND_VARIABLE(SVARIABLE_NAME => 'EDCTRL_CONTR', + NVALUE => PKG_COND_BROKER.GET_CONDITION_NUM(SCONDITION_NAME => 'EDCTRL_CONTR')); + end if; + /* Контроль соисполнения */ + if (PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'EDCTRL_COEXEC') = 1) then + PKG_COND_BROKER.ADD_CLAUSE(SCLAUSE => 'PKG_P8PANELS_PROJECTS.STAGES_GET_CTRL_COEXEC(RN) = :EDCTRL_COEXEC'); + PKG_COND_BROKER.BIND_VARIABLE(SVARIABLE_NAME => 'EDCTRL_COEXEC', + NVALUE => PKG_COND_BROKER.GET_CONDITION_NUM(SCONDITION_NAME => 'EDCTRL_COEXEC')); + end if; + /* Контроль сроков */ + if (PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'EDCTRL_PERIOD') = 1) then + PKG_COND_BROKER.ADD_CLAUSE(SCLAUSE => 'PKG_P8PANELS_PROJECTS.STAGES_GET_CTRL_PERIOD(RN) = :EDCTRL_PERIOD'); + PKG_COND_BROKER.BIND_VARIABLE(SVARIABLE_NAME => 'EDCTRL_PERIOD', + NVALUE => PKG_COND_BROKER.GET_CONDITION_NUM(SCONDITION_NAME => 'EDCTRL_PERIOD')); + end if; + /* Контроль затрат */ + if (PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'EDCTRL_COST') = 1) then + PKG_COND_BROKER.ADD_CLAUSE(SCLAUSE => 'PKG_P8PANELS_PROJECTS.STAGES_GET_CTRL_COST(RN) = :EDCTRL_COST'); + PKG_COND_BROKER.BIND_VARIABLE(SVARIABLE_NAME => 'EDCTRL_COST', + NVALUE => PKG_COND_BROKER.GET_CONDITION_NUM(SCONDITION_NAME => 'EDCTRL_COST')); + end if; + end STAGES_COND; + + /* Подбор платежей финансирования этапа проекта */ + procedure STAGES_SELECT_FIN + ( + NPRN in number := null, -- Рег. номер проекта (null - не отбирать по проекту) + NRN in number := null, -- Рег. номер этапа проекта (null - не отбирать по этапу) + NDIRECTION in number, -- Направление (0 - приход, 1 - расход) + NIDENT out number -- Идентификатор буфера подобранных (списка отмеченных записей, null - не найдено) + ) + is + NSELECTLIST PKG_STD.TREF; -- Рег. номер добавленной записи буфера подобранных + begin + /* Подберём платежи */ + for C in (select PN.COMPANY, + PN.RN + from PAYNOTES PN, + DICTOPER O + where PN.COMPANY in (select PS.COMPANY + from PROJECTSTAGE PS + where ((NRN is null) or ((NRN is not null) and (PS.RN = NRN))) + and ((NPRN is null) or ((NPRN is not null) and (PS.PRN = NPRN)))) + and PN.SIGNPLAN = 0 + and PN.FINOPER = O.RN + and O.TYPOPER_DIRECT = NDIRECTION + and exists (select PNC.RN + from PAYNOTESCLC PNC, + PROJECTSTAGE PS + where PNC.PRN = PN.RN + and PNC.FACEACCOUNT = PS.FACEACC + and ((NRN is null) or ((NRN is not null) and (PS.RN = NRN))) + and ((NPRN is null) or ((NPRN is not null) and (PS.PRN = NPRN))))) + loop + /* Сформируем идентификатор буфера */ + if (NIDENT is null) then + NIDENT := GEN_IDENT(); + end if; + /* Добавим подобранное в список отмеченных записей */ + P_SELECTLIST_BASE_INSERT(NIDENT => NIDENT, + NCOMPANY => C.COMPANY, + NDOCUMENT => C.RN, + SUNITCODE => 'PayNotes', + SACTIONCODE => null, + NCRN => null, + NDOCUMENT1 => null, + SUNITCODE1 => null, + SACTIONCODE1 => null, + NRN => NSELECTLIST); + end loop; + end STAGES_SELECT_FIN; + + /* Получение суммы финансирования этапа проекта */ + function STAGES_GET_FIN + ( + NRN in number, -- Рег. номер этапа проекта + NDIRECTION in number -- Направление (0 - приход, 1 - расход) + ) return number -- Сумма финансирования проекта + is + NRES PKG_STD.TNUMBER; -- Буфер для рузультата + begin + /* Суммируем фактические платежи нужного направления по лицевому счёту затрат этапа */ + select COALESCE(sum(PN.PAY_SUM * (PN.CURR_RATE_BASE/PN.CURR_RATE)), 0) + into NRES + from PAYNOTES PN, + DICTOPER O + where PN.COMPANY in (select PS.COMPANY from PROJECTSTAGE PS where PS.RN = NRN) + and PN.SIGNPLAN = 0 + and PN.FINOPER = O.RN + and O.TYPOPER_DIRECT = NDIRECTION + and exists (select PNC.RN + from PAYNOTESCLC PNC, + PROJECTSTAGE PS + where PNC.PRN = PN.RN + and PNC.FACEACCOUNT = PS.FACEACC + and PS.RN = NRN); + /* Возвращаем результат */ + return NRES; + end STAGES_GET_FIN; + + /* Получение суммы входящего финансирования этапа проекта */ + function STAGES_GET_FIN_IN + ( + NRN in number -- Рег. номер этапа проекта + ) return number -- Сумма входящего финансирования проекта + is + begin + return STAGES_GET_FIN(NRN => NRN, NDIRECTION => 0); + end STAGES_GET_FIN_IN; + + /* Получение суммы исходящего финансирования этапа проекта */ + function STAGES_GET_FIN_OUT + ( + NRN in number -- Рег. номер этапа проекта + ) return number -- Сумма исходяшего финансирования проекта + is + begin + return STAGES_GET_FIN(NRN => NRN, NDIRECTION => 1); + end STAGES_GET_FIN_OUT; + + /* Получение состояния финансирования этапа проекта */ + function STAGES_GET_CTRL_FIN + ( + NRN in number -- Рег. номер этапа проекта + ) return number -- Состояние (0 - без отклонений, 1 - есть отклонения) + is + begin + return 0; + end STAGES_GET_CTRL_FIN; + + /* Получение состояния контрактации этапа проекта */ + function STAGES_GET_CTRL_CONTR + ( + NRN in number -- Рег. номер этапа проекта + ) return number -- Состояние (null - не определено, 0 - без отклонений, 1 - есть отклонения) + is + RSTAGE_ARTS TSTAGE_ARTS; -- Сведения о контрактации по статьям этапа + NCNT_NULL PKG_STD.TNUMBER := 0; -- Количество статей с неопределённым состоянием + begin + /* Получим сведения о контрактации по статьям */ + STAGE_ARTS_GET(NSTAGE => NRN, NINC_CONTR => 1, RSTAGE_ARTS => RSTAGE_ARTS); + /* Если сведения есть - будем разбираться */ + if ((RSTAGE_ARTS is not null) and (RSTAGE_ARTS.COUNT > 0)) then + for I in RSTAGE_ARTS.FIRST .. RSTAGE_ARTS.LAST + loop + if (RSTAGE_ARTS(I).NCTRL_CONTR is null) then + NCNT_NULL := NCNT_NULL + 1; + end if; + /* Если хоть одна статья имеет отклонения */ + if (RSTAGE_ARTS(I).NCTRL_CONTR = 1) then + /* То и этап имеет отклонение */ + return 1; + end if; + end loop; + /* Если ни одна статья не подлежит контролю - то и состояние этапа тоже */ + if (NCNT_NULL = RSTAGE_ARTS.COUNT) then + return null; + end if; + /* Если мы здесь - отклонений нет */ + return 0; + else + /* Нет данных по статьям */ + return null; + end if; + end STAGES_GET_CTRL_CONTR; + + /* Получение состояния соисполнения этапа проекта */ + function STAGES_GET_CTRL_COEXEC + ( + NRN in number -- Рег. номер этапа проекта + ) return number -- Состояние (0 - без отклонений, 1 - есть отклонения) + is + begin + return 0; + end STAGES_GET_CTRL_COEXEC; + + /* Получение состояния сроков этапа проекта */ + function STAGES_GET_CTRL_PERIOD + ( + NRN in number -- Рег. номер этапа проекта + ) return number -- Состояние (null - не определено, 0 - без отклонений, 1 - есть отклонения) + is + NDAYS_LEFT PKG_STD.TNUMBER; -- Остаток дней до завершения этапа + begin + /* Получим количество дней до завершения */ + NDAYS_LEFT := STAGES_GET_DAYS_LEFT(NRN => NRN); + /* Если мы не знаем количества дней - то не можем и контролировать */ + if (NDAYS_LEFT is null) then + return null; + end if; + /* Если осталось меньше определённого лимита */ + if (NDAYS_LEFT < NDAYS_LEFT_LIMIT) then + /* На это необходимо обратить внимание */ + return 1; + else + /* Отклонений нет */ + return 0; + end if; + end STAGES_GET_CTRL_PERIOD; + + /* Получение состояния затрат этапа проекта */ + function STAGES_GET_CTRL_COST + ( + NRN in number -- Рег. номер этапа проекта + ) return number -- Состояние (null - не определено, 0 - без отклонений, 1 - есть отклонения) + is + RSTAGE_ARTS TSTAGE_ARTS; -- Сведения о затратах по статьям этапа + NCNT_NULL PKG_STD.TNUMBER := 0; -- Количество статей с неопределённым состоянием + begin + /* Получим сведения о затратах по статьям */ + STAGE_ARTS_GET(NSTAGE => NRN, NINC_COST => 1, RSTAGE_ARTS => RSTAGE_ARTS); + /* Если сведения есть - будем разбираться */ + if ((RSTAGE_ARTS is not null) and (RSTAGE_ARTS.COUNT > 0)) then + for I in RSTAGE_ARTS.FIRST .. RSTAGE_ARTS.LAST + loop + if (RSTAGE_ARTS(I).NCTRL_COST is null) then + NCNT_NULL := NCNT_NULL + 1; + end if; + /* Если хоть одна статья имеет отклонения */ + if (RSTAGE_ARTS(I).NCTRL_COST = 1) then + /* То и этап имеет отклонение */ + return 1; + end if; + end loop; + /* Если ни одна статья не подлежит контролю - то и состояние этапа тоже */ + if (NCNT_NULL = RSTAGE_ARTS.COUNT) then + return null; + end if; + /* Если мы здесь - отклонений нет */ + return 0; + else + /* Нет данных по статьям */ + return null; + end if; + end STAGES_GET_CTRL_COST; + + /* Получение состояния актирования этапа проекта */ + function STAGES_GET_CTRL_ACT + ( + NRN in number -- Рег. номер этапа проекта + ) return number -- Состояние (0 - без отклонений, 1 - есть отклонения) + is + begin + return 1; + end STAGES_GET_CTRL_ACT; + + /* Получение остатка срока исполнения этапа проекта */ + function STAGES_GET_DAYS_LEFT + ( + NRN in number -- Рег. номер этапа проекта + ) return number -- Количество дней (null - не определено) + is + RSTG PROJECTSTAGE%rowtype; -- Запись этапа + begin + /* Считаем этап */ + RSTG := STAGES_GET(NRN => NRN); + /* Вернём остаток дней */ + if (RSTG.ENDPLAN is not null) then + return RSTG.ENDPLAN - sysdate; + else + return null; + end if; + end STAGES_GET_DAYS_LEFT; + + /* Подбор записей журнала затрат этапа проекта */ + procedure STAGES_SELECT_COST_FACT + ( + NRN in number, -- Рег. номер этапа проекта (null - не отбирать по этапу) + NIDENT out number -- Идентификатор буфера подобранных (списка отмеченных записей, null - не найдено) + ) + is + begin + STAGE_ARTS_SELECT_COST_FACT(NSTAGE => NRN, NFINFLOW_TYPE => 2, NIDENT => NIDENT); + end STAGES_SELECT_COST_FACT; + + /* Получение суммы фактических затрат этапа проекта */ + function STAGES_GET_COST_FACT + ( + NRN in number -- Рег. номер этапа проекта + ) return number -- Сумма фактических затрат + is + begin + return STAGE_ARTS_GET_COST_FACT(NSTAGE => NRN, NFINFLOW_TYPE => 2); + end STAGES_GET_COST_FACT; + + /* Получение суммы реализации этапа проекта */ + function STAGES_GET_SUMM_REALIZ + ( + NRN in number, -- Рег. номер этапа проекта + NFPDARTCL_REALIZ in number -- Рег. номер статьи калькуляции для реализации + ) return number -- Сумма реализации + is + begin + if (NFPDARTCL_REALIZ is not null) then + return STAGE_ARTS_GET_COST_FACT(NSTAGE => NRN, NFPDARTCL => NFPDARTCL_REALIZ); + else + return 0; + end if; + end STAGES_GET_SUMM_REALIZ; + + /* Список этапов */ + procedure STAGES_LIST + ( + NPRN in number, -- Рег. номер проекта + NPAGE_NUMBER in number, -- Номер страницы (игнорируется при NPAGE_SIZE=0) + NPAGE_SIZE in number, -- Количество записей на странице (0 - все) + CFILTERS in clob, -- Фильтры + CORDERS in clob, -- Сортировки + NINCLUDE_DEF in number, -- Признак включения описания колонок таблицы в ответ + COUT out clob -- Сериализованная таблица данных + ) + is + NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса + NIDENT PKG_STD.TREF := GEN_IDENT(); -- Идентификатор отбора + RF PKG_P8PANELS_VISUAL.TFILTERS; -- Фильтры + RO PKG_P8PANELS_VISUAL.TORDERS; -- Сортировки + RDG PKG_P8PANELS_VISUAL.TDATA_GRID; -- Описание таблицы + RDG_ROW PKG_P8PANELS_VISUAL.TROW; -- Строка таблицы + RCOL_VALS PKG_P8PANELS_VISUAL.TCOL_VALS; -- Предопределённые значения столбцов + NROW_FROM PKG_STD.TREF; -- Номер строки с + NROW_TO PKG_STD.TREF; -- Номер строки по + NFPDARTCL_REALIZ PKG_STD.TREF; -- Рег. номер статьи калькуляции для реализации + CSQL clob; -- Буфер для запроса + ICURSOR integer; -- Курсор для исполнения запроса + NCOST_FACT PKG_STD.TNUMBER; -- Сумма фактических затрат по этапу проекта + NSUMM_REALIZ PKG_STD.TNUMBER; -- Сумма реализации по этапу проекта + NSUMM_INCOME PKG_STD.TNUMBER; -- Сумма прибыли по этапу проекта + NINCOME_PRC PKG_STD.TNUMBER; -- Процент прибыли по этапу проекта + begin + /* Определим рег. номер статьи калькуляции для учёта реализации */ + FIND_FPDARTCL_CODE(NFLAG_SMART => 1, NCOMPANY => NCOMPANY, SCODE => SFPDARTCL_REALIZ, NRN => NFPDARTCL_REALIZ); + /* Читаем фильтры */ + RF := PKG_P8PANELS_VISUAL.TFILTERS_FROM_XML(CFILTERS => CFILTERS); + /* Читем сортировки */ + RO := PKG_P8PANELS_VISUAL.TORDERS_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.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 => 'SNUMB', + SCAPTION => 'Номер', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + SCOND_FROM => 'EDNUMB', + BORDER => true, + BFILTER => true); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'SNAME', + SCAPTION => 'Наименование', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + SCOND_FROM => 'EDNAME', + BORDER => true, + BFILTER => true); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'SEXPECTED_RES', + SCAPTION => 'Ожидаемые результаты', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'SFACEACC', + SCAPTION => 'Шифр затрат', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 0, BCLEAR => true); + PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 1); + PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 2); + PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 3); + PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 4); + PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 5); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NSTATE', + SCAPTION => 'Состояние', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, + SCOND_FROM => 'CGSTATE', + BORDER => true, + BFILTER => true, + RCOL_VALS => RCOL_VALS); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'DBEGPLAN', + SCAPTION => 'Дата начала', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_DATE, + SCOND_FROM => 'EDPLANBEGFrom', + SCOND_TO => 'EDPLANBEGTo', + BORDER => true, + BFILTER => true); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'DENDPLAN', + SCAPTION => 'Дата окончания', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_DATE, + SCOND_FROM => 'EDPLANENDFrom', + SCOND_TO => 'EDPLANENDTo', + BORDER => true, + BFILTER => true); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NCOST_SUM', + SCAPTION => 'Стоимость', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'SCURNAMES', + SCAPTION => 'Валюта', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NFIN_IN', + SCAPTION => 'Входящее финансирование', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'SLNK_UNIT_NFIN_IN', + SCAPTION => 'Входящее финансирование (код раздела ссылки)', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NLNK_DOCUMENT_NFIN_IN', + SCAPTION => 'Входящее финансирование (документ ссылки)', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NFIN_OUT', + SCAPTION => 'Исходящее финансирование', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'SLNK_UNIT_NFIN_OUT', + SCAPTION => 'Исходящее финансирование (код раздела ссылки)', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NLNK_DOCUMENT_NFIN_OUT', + SCAPTION => 'Исходящее финансирование (документ ссылки)', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 0, BCLEAR => true); + PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 1); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NCTRL_FIN', + SCAPTION => 'Финансирование', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, + SCOND_FROM => 'EDCTRL_FIN', + BORDER => true, + BFILTER => true, + RCOL_VALS => RCOL_VALS); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NCTRL_CONTR', + SCAPTION => 'Контрактация', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, + SCOND_FROM => 'EDCTRL_CONTR', + BORDER => true, + BFILTER => true, + RCOL_VALS => RCOL_VALS); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NCTRL_COEXEC', + SCAPTION => 'Соисполнители', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, + SCOND_FROM => 'EDCTRL_COEXEC', + BORDER => true, + BFILTER => true, + RCOL_VALS => RCOL_VALS); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NDAYS_LEFT', + SCAPTION => 'Дней до окончания', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NCTRL_PERIOD', + SCAPTION => 'Сроки', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, + SCOND_FROM => 'EDCTRL_PERIOD', + BORDER => true, + BFILTER => true, + RCOL_VALS => RCOL_VALS); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NCOST_FACT', + SCAPTION => 'Сумма фактических затрат', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'SLNK_UNIT_NCOST_FACT', + SCAPTION => 'Сумма фактических затрат (код раздела ссылки)', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NLNK_DOCUMENT_NCOST_FACT', + SCAPTION => 'Сумма фактических затрат (документ ссылки)', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NSUMM_REALIZ', + SCAPTION => 'Сумма реализации', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NSUMM_INCOME', + SCAPTION => 'Сумма прибыли', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NINCOME_PRC', + SCAPTION => 'Процент прибыли', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NCTRL_COST', + SCAPTION => 'Затраты', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, + SCOND_FROM => 'EDCTRL_COST', + BORDER => true, + BFILTER => true, + RCOL_VALS => RCOL_VALS); + /* Обходим данные */ + begin + /* Собираем запрос */ + CSQL := 'select * + from (select D.*, + ROWNUM NROW + from (select PS.RN NRN, + PS.NUMB SNUMB, + PS.NAME SNAME, + PS.EXPECTED_RES SEXPECTED_RES, + FAC.NUMB SFACEACC, + PS.STATE NSTATE, + PS.BEGPLAN DBEGPLAN, + PS.ENDPLAN DENDPLAN, + PS.COST_SUM_BASECURR NCOST_SUM, + CN.INTCODE SCURNAMES, + PKG_P8PANELS_PROJECTS.STAGES_GET_FIN_IN(PS.RN) NFIN_IN, + ''Paynotes'' SLNK_UNIT_NFIN_IN, + 0 NLNK_DOCUMENT_NFIN_IN, + PKG_P8PANELS_PROJECTS.STAGES_GET_FIN_OUT(PS.RN) NFIN_OUT, + ''Paynotes'' SLNK_UNIT_NFIN_OUT, + 1 NLNK_DOCUMENT_NFIN_OUT, + PKG_P8PANELS_PROJECTS.STAGES_GET_CTRL_FIN(PS.RN) NCTRL_FIN, + PKG_P8PANELS_PROJECTS.STAGES_GET_CTRL_CONTR(PS.RN) NCTRL_CONTR, + PKG_P8PANELS_PROJECTS.STAGES_GET_CTRL_COEXEC(PS.RN) NCTRL_COEXEC, + PKG_P8PANELS_PROJECTS.STAGES_GET_DAYS_LEFT(PS.RN) NDAYS_LEFT, + PKG_P8PANELS_PROJECTS.STAGES_GET_CTRL_PERIOD(PS.RN) NCTRL_PERIOD, + PKG_P8PANELS_PROJECTS.STAGES_GET_COST_FACT(PS.RN) NCOST_FACT, + ''CostNotes'' SLNK_UNIT_NCOST_FACT, + 1 NLNK_DOCUMENT_NCOST_FACT, + PKG_P8PANELS_PROJECTS.STAGES_GET_SUMM_REALIZ(PS.RN, :NFPDARTCL_REALIZ) NSUMM_REALIZ, + PKG_P8PANELS_PROJECTS.STAGES_GET_CTRL_COST(PS.RN) NCTRL_COST + from PROJECTSTAGE PS, + PROJECT P, + FACEACC FAC, + CURNAMES CN + where PS.PRN = P.RN + and PS.FACEACC = FAC.RN(+) + and P.CURNAMES = CN.RN + and PS.RN in (select ID from COND_BROKER_IDSMART where IDENT = :NIDENT) %ORDER_BY%) D) F + where F.NROW between :NROW_FROM and :NROW_TO'; + /* Учтём сортировки */ + PKG_P8PANELS_VISUAL.TORDERS_SET_QUERY(RDATA_GRID => RDG, RORDERS => RO, SPATTERN => '%ORDER_BY%', CSQL => CSQL); + /* Учтём фильтры */ + PKG_P8PANELS_VISUAL.TFILTERS_SET_QUERY(NIDENT => NIDENT, + NCOMPANY => NCOMPANY, + NPARENT => NPRN, + SUNIT => 'ProjectsStages', + SPROCEDURE => 'PKG_P8PANELS_PROJECTS.STAGES_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.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NFPDARTCL_REALIZ', NVALUE => NFPDARTCL_REALIZ); + /* Описываем структуру записи курсора */ + PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 1); + PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 2); + PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 3); + PKG_SQL_DML.DEFINE_COLUMN_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); + PKG_SQL_DML.DEFINE_COLUMN_DATE(ICURSOR => ICURSOR, IPOSITION => 7); + PKG_SQL_DML.DEFINE_COLUMN_DATE(ICURSOR => ICURSOR, IPOSITION => 8); + PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 9); + PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 10); + PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 11); + PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 12); + PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 13); + PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 14); + PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 15); + PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 16); + PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 17); + PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 18); + PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 19); + PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 20); + PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 21); + PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 22); + PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 23); + PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 24); + PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 25); + PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 26); + /* Делаем выборку */ + if (PKG_SQL_DML.EXECUTE(ICURSOR => ICURSOR) = 0) then + null; + end if; + /* Обходим выбранные записи */ + while (PKG_SQL_DML.FETCH_ROWS(ICURSOR => ICURSOR) > 0) + loop + /* Добавляем колонки с данными */ + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, + SNAME => 'NRN', + ICURSOR => ICURSOR, + NPOSITION => 1, + BCLEAR => true); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SNUMB', ICURSOR => ICURSOR, NPOSITION => 2); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SNAME', ICURSOR => ICURSOR, NPOSITION => 3); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, + SNAME => 'SEXPECTED_RES', + ICURSOR => ICURSOR, + NPOSITION => 4); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SFACEACC', ICURSOR => ICURSOR, NPOSITION => 5); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NSTATE', ICURSOR => ICURSOR, NPOSITION => 6); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLD(RROW => RDG_ROW, SNAME => 'DBEGPLAN', ICURSOR => ICURSOR, NPOSITION => 7); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLD(RROW => RDG_ROW, SNAME => 'DENDPLAN', ICURSOR => ICURSOR, NPOSITION => 8); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, + SNAME => 'NCOST_SUM', + ICURSOR => ICURSOR, + NPOSITION => 9); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, + SNAME => 'SCURNAMES', + ICURSOR => ICURSOR, + NPOSITION => 10); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NFIN_IN', ICURSOR => ICURSOR, NPOSITION => 11); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, + SNAME => 'SLNK_UNIT_NFIN_IN', + ICURSOR => ICURSOR, + NPOSITION => 12); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, + SNAME => 'NLNK_DOCUMENT_NFIN_IN', + ICURSOR => ICURSOR, + NPOSITION => 13); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, + SNAME => 'NFIN_OUT', + ICURSOR => ICURSOR, + NPOSITION => 14); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, + SNAME => 'SLNK_UNIT_NFIN_OUT', + ICURSOR => ICURSOR, + NPOSITION => 15); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, + SNAME => 'NLNK_DOCUMENT_NFIN_OUT', + ICURSOR => ICURSOR, + NPOSITION => 16); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, + SNAME => 'NCTRL_FIN', + ICURSOR => ICURSOR, + NPOSITION => 17); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, + SNAME => 'NCTRL_CONTR', + ICURSOR => ICURSOR, + NPOSITION => 18); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, + SNAME => 'NCTRL_COEXEC', + ICURSOR => ICURSOR, + NPOSITION => 19); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, + SNAME => 'NDAYS_LEFT', + ICURSOR => ICURSOR, + NPOSITION => 20); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, + SNAME => 'NCTRL_PERIOD', + ICURSOR => ICURSOR, + NPOSITION => 21); + PKG_SQL_DML.COLUMN_VALUE_NUM(ICURSOR => ICURSOR, IPOSITION => 22, NVALUE => NCOST_FACT); + PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NCOST_FACT', NVALUE => NCOST_FACT); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, + SNAME => 'SLNK_UNIT_NCOST_FACT', + ICURSOR => ICURSOR, + NPOSITION => 23); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, + SNAME => 'NLNK_DOCUMENT_NCOST_FACT', + ICURSOR => ICURSOR, + NPOSITION => 24); + PKG_SQL_DML.COLUMN_VALUE_NUM(ICURSOR => ICURSOR, IPOSITION => 25, NVALUE => NSUMM_REALIZ); + if (NSUMM_REALIZ = 0) then + NSUMM_INCOME := 0; + NINCOME_PRC := 0; + else + NSUMM_INCOME := NSUMM_REALIZ - NCOST_FACT; + NINCOME_PRC := NSUMM_INCOME / NCOST_FACT * 100; + end if; + PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NSUMM_REALIZ', NVALUE => NSUMM_REALIZ); + PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NSUMM_INCOME', NVALUE => NSUMM_INCOME); + PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NINCOME_PRC', NVALUE => NINCOME_PRC); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, + SNAME => 'NCTRL_COST', + ICURSOR => ICURSOR, + NPOSITION => 26); + /* Добавляем строку в таблицу */ + PKG_P8PANELS_VISUAL.TDATA_GRID_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.TDATA_GRID_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => NINCLUDE_DEF); + end STAGES_LIST; + + /* Считывание записи проекта/этапа для расчётной таблицы "PM0010" - "Калькуляция этапа проекта" */ + procedure STAGES_CT_CALC_LOAD_PROJECT + ( + RPRJ out PROJECT%rowtype, -- Запись проекта + RSTG out PROJECTSTAGE%rowtype -- Запись этапа проекта + ) + is + NCOMPANY PKG_STD.TREF; -- Рег. номер организации из входных параметров + SPROJECT_CODE PKG_STD.TSTRING; -- Код проета из параметров + SPROJECT_STAGE_NUMB PKG_STD.TSTRING; -- Номер этапа проекта из входных параметров + begin + /* Считывание параметра "Организация" */ + PRSG_CALCTAB_IMAGE.READ_PARAMETER_NUM(SNAME => SSTAGES_CT_CALC_PRM_COMP, NVALUE => NCOMPANY); + /* Считывание параметра "Код проекта" */ + PRSG_CALCTAB_IMAGE.READ_PARAMETER_STR(SNAME => SSTAGES_CT_CALC_PRM_PRJ, SVALUE => SPROJECT_CODE); + /* Считывание параметра "Номер этапа проекта" */ + PRSG_CALCTAB_IMAGE.READ_PARAMETER_STR(SNAME => SSTAGES_CT_CALC_PRM_STG, SVALUE => SPROJECT_STAGE_NUMB); + /* Читаем данные */ + begin + /* Проект */ + select P.* + into RPRJ + from PROJECT P + where P.COMPANY = NCOMPANY + and P.CODE = SPROJECT_CODE; + /* Этап */ + select PS.* + into RSTG + from PROJECTSTAGE PS + where PS.PRN = RPRJ.RN + and trim(PS.NUMB) = trim(SPROJECT_STAGE_NUMB); + exception + when NO_DATA_FOUND then + P_EXCEPTION(0, + 'Этап "%s" проекта "%s" в организации "%s" не определён.', + COALESCE(SPROJECT_STAGE_NUMB, '<НЕ УКАЗАН>'), + COALESCE(SPROJECT_CODE, '<НЕ УКАЗАН>'), + COALESCE(TO_CHAR(NCOMPANY), '<НЕ УКАЗАНА>')); + end; + end STAGES_CT_CALC_LOAD_PROJECT; + + /* Формирование заголовков таблиц для расчётной таблицы "PM0010" - "Калькуляция этапа проекта" */ + procedure STAGES_CT_CALC_TABLE_CAPTIONS + is + RPRJ PROJECT%rowtype; -- Запись проекта + RSTG PROJECTSTAGE%rowtype; -- Запись этапа проекта + begin + /* Считаем проект и этап */ + STAGES_CT_CALC_LOAD_PROJECT(RPRJ => RPRJ, RSTG => RSTG); + /* Работаем от имени таблицы */ + case PRSG_CALCTAB.TABLE_NAME + /* Таблица "Статьи калькуляции" */ + when SSTAGES_CT_CALC_TBL_CLARTS then + PRSG_CALCTAB_BUILD.WRITE_TABLE_CAPTION(STEXT => 'Калькуляция этапа "' || trim(RSTG.NUMB) || '" проекта "' || + RPRJ.CODE || '"'); + /* Неизвестная таблица */ + else + null; + end case; + end STAGES_CT_CALC_TABLE_CAPTIONS; + + /* Формирование строк для расчетной таблицы "PM0010" - "Калькуляция этапа проекта" */ + procedure STAGES_CT_CALC_BUILD_LINES + is + NCOMPANY PKG_STD.TREF; -- Рег. номер организации из входных параметров + NVERSION PKG_STD.TREF; -- Рег. номер версии словаря "Статьи затрат" + SCRN PKG_STD.TSTRING; -- Наименование каталога статей калькуляции в словаре "Статьи затрат" + NCRN PKG_STD.TREF; -- Рег. номер каталога статей калькуляции в словаре "Статьи затрат" + BCREATED boolean := false; -- Флаг успешного добавления строк в таблицу + begin + /* Строки для таблицы "Статьи калькуляции" */ + if (PRSG_CALCTAB.TABLE_NAME = SSTAGES_CT_CALC_TBL_CLARTS) then + /* Считывание параметра "Организация" */ + PRSG_CALCTAB_IMAGE.READ_PARAMETER_NUM(SNAME => SSTAGES_CT_CALC_PRM_COMP, NVALUE => NCOMPANY); + /* Считывание параметра "Каталог статей калькуляции" */ + PRSG_CALCTAB_IMAGE.READ_PARAMETER_STR(SNAME => SSTAGES_CT_CALC_PRM_ARTSCAT, SVALUE => SCRN); + /* Находим версию словаря "Статьи затрат" */ + FIND_VERSION_BY_COMPANY(NCOMPANY => NCOMPANY, SUNITCODE => 'FinPlanArticles', NVERSION => NVERSION); + /* Находим рег. номер каталога статей калькуляции */ + FIND_ACATALOG_NAME(NFLAG_SMART => 0, + NCOMPANY => NCOMPANY, + NVERSION => NVERSION, + SUNITCODE => 'FinPlanArticles', + SNAME => SCRN, + NRN => NCRN); + /* Идем по статьям калькуляции */ + for C in (select T.RN + from FPDARTCL T + where T.VERSION = NVERSION + and T.CRN = NCRN + order by T.CODE) + loop + /* Добавим строку */ + PRSG_CALCTAB_BUILD.APPEND_ROW_COPY(NSOURCE => C.RN); + /* Поднимем флаг добавления */ + BCREATED := true; + end loop; + /* Если статей не нашли */ + if (not BCREATED) then + P_EXCEPTION(0, 'Не задан набор статей калькуляции.'); + end if; + end if; + end STAGES_CT_CALC_BUILD_LINES; + + /* Наполнение строк для расчетной таблицы "PM0010" - "Калькуляция этапа проекта" */ + procedure STAGES_CT_CALC_FILL_LINES + is + RCURSOR PRSG_CALCTAB.TCURSOR; -- Маркер коллекции строк таблицы + RFPDARTCL FPDARTCL%rowtype; -- Запись статьи калькуляции в словаре + NSUMM_PL PKG_STD.TNUMBER; -- Плановая сумма (считанная из хранилища расчётной таблицы) + begin + /* Выбор листа и таблицы "Статьи калькуляции"*/ + PRSG_CALCTAB_IMAGE.SELECT_TABLE(SSHEET_NAME => SSTAGES_CT_CALC_SH_CACL, STABLE_NAME => SSTAGES_CT_CALC_TBL_CLARTS); + /* Первая строка */ + PRSG_CALCTAB_IMAGE.FIRST_ROW(SROW_NAME => SSTAGES_CT_CALC_LN_ARTS, RCURSOR => RCURSOR); + /* Цикл по строкам */ + loop + /* Cчитаем статью */ + begin + select A.* into RFPDARTCL from FPDARTCL A where A.RN = RCURSOR.ROW_SOURCE; + exception + when NO_DATA_FOUND then + PKG_MSG.RECORD_NOT_FOUND(NFLAG_SMART => 0, NDOCUMENT => RCURSOR.ROW_SOURCE, SUNIT_TABLE => 'FPDARTCL'); + end; + /* Заполняем колонки - "Номер" */ + PRSG_CALCTAB_IMAGE.WRITE_ROW_STR(RCURSOR => RCURSOR, + SCOLUMN_NAME => SSTAGES_CT_CALC_CL_NUMB, + SVALUE => RFPDARTCL.CODE, + NSOURCE => RFPDARTCL.RN); + /* Заполняем колонки - "Наименование" */ + PRSG_CALCTAB_IMAGE.WRITE_ROW_STR(RCURSOR => RCURSOR, + SCOLUMN_NAME => SSTAGES_CT_CALC_CL_NAME, + SVALUE => RFPDARTCL.NAME, + NSOURCE => RFPDARTCL.RN); + /* Заполняем колонки - "Плановая сумма" */ + PRSG_CALCTAB_IMAGE.READ_ROW_NUM(RCURSOR => RCURSOR, + SCOLUMN_NAME => SSTAGES_CT_CALC_CL_SUMM_PL, + NVALUE => NSUMM_PL); + PRSG_CALCTAB_IMAGE.WRITE_ROW_NUM(RCURSOR => RCURSOR, + SCOLUMN_NAME => SSTAGES_CT_CALC_CL_SUMM_PL, + NVALUE => COALESCE(NSUMM_PL, 0), + NSOURCE => RFPDARTCL.RN); + /* Выходим если строк больше нет */ + if (not PRSG_CALCTAB_IMAGE.NEXT_ROW(RCURSOR => RCURSOR)) then + exit; + end if; + end loop; + end STAGES_CT_CALC_FILL_LINES; + + /* Формирование расчетной таблицы "PM0010" - "Калькуляция этапа проекта" */ + procedure STAGES_CT_CALC + is + begin + /* Работаем в зависимости от текущего режима вызова */ + case + /* Инициализация построения */ + when (PRSG_CALCTAB.CONTEXT_INIT) then + null; + /* Формирование заголовков листов */ + when (PRSG_CALCTAB.CONTEXT_SHEET_CAPTION) then + null; + /* Формирование заголовков таблиц */ + when (PRSG_CALCTAB.CONTEXT_TABLE_CAPTION) then + STAGES_CT_CALC_TABLE_CAPTIONS(); + /* Формирование столбцов */ + when (PRSG_CALCTAB.CONTEXT_COLUMN_CAPTION) then + null; + /* Формирование строк */ + when (PRSG_CALCTAB.CONTEXT_ROW_COPIES) then + STAGES_CT_CALC_BUILD_LINES(); + /* Наполнение данными */ + when (PRSG_CALCTAB.CONTEXT_BEFORE) then + STAGES_CT_CALC_FILL_LINES(); + /* Сохранение */ + when (PRSG_CALCTAB.CONTEXT_AFTER) then + null; + /* Прочее */ + else + null; + end case; + end STAGES_CT_CALC; + + /* Подбор записей журнала затрат по статье калькуляции этапа проекта */ + procedure STAGE_ARTS_SELECT_COST_FACT + ( + NSTAGE in number, -- Рег. номер этапа проекта + NFPDARTCL in number := null, -- Рег. номер статьи калькуляции (null - по всем) + NFINFLOW_TYPE in number := null, -- Вид движения по статье (null - по всем, 0 - остаток, 1 - приход, 2 - расход) + NIDENT out number -- Идентификатор буфера подобранных (списка отмеченных записей, null - не найдено) + ) + is + NSELECTLIST PKG_STD.TREF; -- Рег. номер добавленной записи буфера подобранных + begin + /* Подберём записи журнала затрат */ + for C in (select CN.COMPANY, + CN.RN + from PROJECTSTAGE PS, + FCCOSTNOTES CN, + FINSTATE FS, + FPDARTCL FA, + FINFLOWTYPE FT + where PS.RN = NSTAGE + and PS.FACEACC = CN.PROD_ORDER + and ((NFPDARTCL is null) or ((NFPDARTCL is not null) and (CN.COST_ARTICLE = NFPDARTCL))) + and CN.COST_TYPE = FS.RN + and FS.TYPE = 1 + and CN.COST_ARTICLE = FA.RN + and FA.DEF_FLOW = FT.RN(+) + and ((NFINFLOW_TYPE is null) or ((NFINFLOW_TYPE is not null) and (FT.TYPE = NFINFLOW_TYPE)))) + loop + /* Сформируем идентификатор буфера */ + if (NIDENT is null) then + NIDENT := GEN_IDENT(); + end if; + /* Добавим подобранное в список отмеченных записей */ + P_SELECTLIST_BASE_INSERT(NIDENT => NIDENT, + NCOMPANY => C.COMPANY, + NDOCUMENT => C.RN, + SUNITCODE => 'CostNotes', + SACTIONCODE => null, + NCRN => null, + NDOCUMENT1 => null, + SUNITCODE1 => null, + SACTIONCODE1 => null, + NRN => NSELECTLIST); + end loop; + end STAGE_ARTS_SELECT_COST_FACT; + + /* Получение суммы-факт по статье калькуляции этапа проекта */ + function STAGE_ARTS_GET_COST_FACT + ( + NSTAGE in number, -- Рег. номер этапа проекта + NFPDARTCL in number := null, -- Рег. номер статьи калькуляции (null - по всем) + NFINFLOW_TYPE in number := null -- Вид движения по статье (null - по всем, 0 - остаток, 1 - приход, 2 - расход) + ) return number -- Сумма-факт по статье + is + NRES PKG_STD.TNUMBER; -- Буфер для рузультата + begin + /* Суммируем факт по лицевому счёту затрат этапа и указанной статье */ + select COALESCE(sum(CN.COST_BSUM), 0) + into NRES + from PROJECTSTAGE PS, + FCCOSTNOTES CN, + FINSTATE FS, + FPDARTCL FA, + FINFLOWTYPE FT + where PS.RN = NSTAGE + and PS.FACEACC = CN.PROD_ORDER + and ((NFPDARTCL is null) or ((NFPDARTCL is not null) and (CN.COST_ARTICLE = NFPDARTCL))) + and CN.COST_TYPE = FS.RN + and FS.TYPE = 1 + and CN.COST_ARTICLE = FA.RN + and FA.DEF_FLOW = FT.RN(+) + and ((NFINFLOW_TYPE is null) or ((NFINFLOW_TYPE is not null) and (FT.TYPE = NFINFLOW_TYPE))); + /* Возвращаем результат */ + return NRES; + end STAGE_ARTS_GET_COST_FACT; + + /* Подбор записей договоров с соисполнителями по статье калькуляции этапа проекта */ + procedure STAGE_ARTS_SELECT_CONTR + ( + NSTAGE in number, -- Рег. номер этапа проекта + NFPDARTCL in number := null, -- Рег. номер статьи затрат (null - по всем) + NIDENT out number -- Идентификатор буфера подобранных (списка отмеченных записей, null - не найдено) + ) + is + NSELECTLIST PKG_STD.TREF; -- Рег. номер добавленной записи буфера подобранных + begin + /* Подберём записи договоров */ + for C in (select distinct S.COMPANY NCOMPANY, + S.PRN NRN + from PROJECTSTAGEPF EPF, + STAGES S + where EPF.PRN = NSTAGE + and EPF.FACEACC = S.FACEACC + and ((NFPDARTCL is null) or ((NFPDARTCL is not null) and (EPF.COST_ARTICLE = NFPDARTCL)))) + loop + /* Сформируем идентификатор буфера */ + if (NIDENT is null) then + NIDENT := GEN_IDENT(); + end if; + /* Добавим подобранное в список отмеченных записей */ + P_SELECTLIST_BASE_INSERT(NIDENT => NIDENT, + NCOMPANY => C.NCOMPANY, + NDOCUMENT => C.NRN, + SUNITCODE => 'Contracts', + SACTIONCODE => null, + NCRN => null, + NDOCUMENT1 => null, + SUNITCODE1 => null, + SACTIONCODE1 => null, + NRN => NSELECTLIST); + end loop; + end STAGE_ARTS_SELECT_CONTR; + + /* Получение законтрактованной суммы по статье калькуляции этапа проекта */ + function STAGE_ARTS_GET_CONTR + ( + NSTAGE in number, -- Рег. номер этапа проекта + NFPDARTCL in number :=null -- Рег. номер статьи затрат (null - по всем) + ) return number -- Сумма контрактов по статье + is + RSTG PROJECTSTAGE%rowtype; -- Запись этапа + NTAX_GROUP_DP PKG_STD.TREF; -- Рег. номер доп. свойства для налоговой группы проекта + SPRJ_TAX_GROUP PKG_STD.TSTRING; -- Налоговая группа проекта + NSUM PKG_STD.TNUMBER; -- Сумма контрактов (без налогов) + NSUM_TAX PKG_STD.TNUMBER; -- Сумма контрактов (с налогами) + begin + /* Считаем запись этапа */ + begin + select PS.* into RSTG from PROJECTSTAGE PS where PS.RN = NSTAGE; + exception + when NO_DATA_FOUND then + null; + end; + /* Если считано успешно - будем искать данные */ + if (RSTG.RN is not null) then + /* Определим рег. номер доп. свойства для налоговой группы проекта */ + FIND_DOCS_PROPS_CODE(NFLAG_SMART => 1, + NCOMPANY => RSTG.COMPANY, + SCODE => 'ПУП.TAX_GROUP', + NRN => NTAX_GROUP_DP); + /* Считаем налоговую группу проекта */ + SPRJ_TAX_GROUP := F_DOCS_PROPS_GET_STR_VALUE(NPROPERTY => NTAX_GROUP_DP, + SUNITCODE => 'Projects', + NDOCUMENT => RSTG.PRN); + /* Считаем сумму этапов договоров с соисполнителями */ + select COALESCE(sum(S.STAGE_SUM), 0), + COALESCE(sum(S.STAGE_SUMTAX), 0) + into NSUM, + NSUM_TAX + from PROJECTSTAGEPF EPF, + STAGES S + where EPF.PRN = RSTG.RN + and EPF.FACEACC = S.FACEACC + and ((NFPDARTCL is null) or ((NFPDARTCL is not null) and (EPF.COST_ARTICLE = NFPDARTCL))); + /* Вернём сумму в зависимости от налоговой группы проекта */ + if (SPRJ_TAX_GROUP is not null) then + return NSUM; + else + return NSUM_TAX; + end if; + else + return 0; + end if; + end STAGE_ARTS_GET_CONTR; + + /* Получение списка статей этапа проекта */ + procedure STAGE_ARTS_GET + ( + NSTAGE in number, -- Рег. номер этапа проекта + NINC_COST in number := 0, -- Включить сведения о затратах (0 - нет, 1 - да) + NINC_CONTR in number := 0, -- Включить сведения о контрактации (0 - нет, 1 - да) + RSTAGE_ARTS out TSTAGE_ARTS -- Список статей этапа проекта + ) + is + RPRJ PROJECT%rowtype; -- Запись проекта + RSTG PROJECTSTAGE%rowtype; -- Запись этапа проекта + NCTL_COST_DP PKG_STD.TREF; -- Рег. номер доп. свойства, определяющего необходимость контроля затрат по статье + NCTL_CONTR_DP PKG_STD.TREF; -- Рег. номер доп. свойства, определяющего необходимость контроля контрактации по статье + NCT PKG_STD.TREF; -- Рег. номер расчётной таблицы + RCURSOR PRSG_CALCTAB.TCURSOR; -- Курсор для обхода строк расчётной таблицы + I PKG_STD.TNUMBER; -- Счётчик статей в результирующей коллекции + begin + /* Читаем проект и этап */ + RSTG := STAGES_GET(NRN => NSTAGE); + RPRJ := GET(NRN => RSTG.PRN); + /* Определим дополнительные свойства - контроль затрат */ + if (NINC_COST = 1) then + FIND_DOCS_PROPS_CODE(NFLAG_SMART => 1, NCOMPANY => RPRJ.COMPANY, SCODE => 'ПУП.CTL_COST', NRN => NCTL_COST_DP); + end if; + /* Определим дополнительные свойства - контроль затрат */ + if (NINC_CONTR = 1) then + FIND_DOCS_PROPS_CODE(NFLAG_SMART => 1, + NCOMPANY => RPRJ.COMPANY, + SCODE => 'ПУП.CTL_CONTR', + NRN => NCTL_CONTR_DP); + end if; + /* Инициализируем коллекцию */ + RSTAGE_ARTS := TSTAGE_ARTS(); + /* Подбираем расчётную таблицу */ + for C in (select CT.RN + from CALCTABCPYS CT + where CT.COMPANY = RPRJ.COMPANY + and exists (select null + from V_CALCTABCPYPRMS P + where P.SPARAMETER_NAME = SSTAGES_CT_CALC_PRM_PRJ + and P.SSTR_VALUE = RPRJ.CODE + and P.NPRN = CT.RN) + and exists (select null + from V_CALCTABCPYPRMS P + where P.SPARAMETER_NAME = SSTAGES_CT_CALC_PRM_STG + and trim(P.SSTR_VALUE) = trim(RSTG.NUMB) + and P.NPRN = CT.RN) + order by CT.DOC_DATE desc) + loop + /* Берём первую найденную и выходим */ + NCT := C.RN; + exit; + end loop; + /* Обходим строки расчётной таблицы если нашли */ + if (NCT is not null) then + /* Попытаемся установить таблицу из хранилища */ + PRSG_CALCTAB_STORE.SELECT_TABLE(NDOCUMENT => NCT, + SSHEET_NAME => SSTAGES_CT_CALC_SH_CACL, + STABLE_NAME => SSTAGES_CT_CALC_TBL_CLARTS); + /* Встаём на первую строку */ + PRSG_CALCTAB_STORE.FIRST_ROW(SROW_NAME => SSTAGES_CT_CALC_LN_ARTS, RCURSOR => RCURSOR); + loop + /* Добавим строку в коллекцию */ + RSTAGE_ARTS.EXTEND(); + I := RSTAGE_ARTS.LAST; + /* Наполним её значениями из хранилища */ + RSTAGE_ARTS(I).NRN := RCURSOR.ROW_SOURCE; + PRSG_CALCTAB_STORE.READ_ROW_STR(RCURSOR => RCURSOR, + SCOLUMN_NAME => SSTAGES_CT_CALC_CL_NUMB, + SVALUE => RSTAGE_ARTS(I).SCODE); + PRSG_CALCTAB_STORE.READ_ROW_STR(RCURSOR => RCURSOR, + SCOLUMN_NAME => SSTAGES_CT_CALC_CL_NAME, + SVALUE => RSTAGE_ARTS(I).SNAME); + PRSG_CALCTAB_STORE.READ_ROW_NUM(RCURSOR => RCURSOR, + SCOLUMN_NAME => SSTAGES_CT_CALC_CL_SUMM_PL, + NVALUE => RSTAGE_ARTS(I).NPLAN); + /* Если просили включить сведения о затратах и статья поддерживает это */ + if ((NINC_COST = 1) and + (UPPER(F_DOCS_PROPS_GET_STR_VALUE(NPROPERTY => NCTL_COST_DP, + SUNITCODE => 'FinPlanArticles', + NDOCUMENT => RSTAGE_ARTS(I).NRN)) = UPPER(SYES)) and RSTAGE_ARTS(I) + .NPLAN is not null) then + /* Фактические затраты по статье */ + RSTAGE_ARTS(I).NCOST_FACT := STAGE_ARTS_GET_COST_FACT(NSTAGE => NSTAGE, NFPDARTCL => RSTAGE_ARTS(I).NRN); + /* Отклонение затрат (план-факт) */ + RSTAGE_ARTS(I).NCOST_DIFF := RSTAGE_ARTS(I).NPLAN - RSTAGE_ARTS(I).NCOST_FACT; + /* Контроль затрат */ + if (RSTAGE_ARTS(I).NCOST_DIFF >= 0) then + RSTAGE_ARTS(I).NCTRL_COST := 0; + else + RSTAGE_ARTS(I).NCTRL_COST := 1; + end if; + end if; + /* Если просили включить сведения о контрактах и статья поддерживает это */ + if (NINC_CONTR = 1) and (UPPER(F_DOCS_PROPS_GET_STR_VALUE(NPROPERTY => NCTL_CONTR_DP, + SUNITCODE => 'FinPlanArticles', + NDOCUMENT => RSTAGE_ARTS(I).NRN)) = + UPPER(SYES) and RSTAGE_ARTS(I).NPLAN is not null) then + /* Законтрактовано */ + RSTAGE_ARTS(I).NCONTR := STAGE_ARTS_GET_CONTR(NSTAGE => NSTAGE, NFPDARTCL => RSTAGE_ARTS(I).NRN); + /* Осталось законтрактовать */ + RSTAGE_ARTS(I).NCONTR_LEFT := RSTAGE_ARTS(I).NPLAN - RSTAGE_ARTS(I).NCONTR; + /* Контроль контрактации */ + if (RSTAGE_ARTS(I).NCONTR_LEFT >= 0) then + RSTAGE_ARTS(I).NCTRL_CONTR := 0; + else + RSTAGE_ARTS(I).NCTRL_CONTR := 1; + end if; + end if; + /* Переход на следующую строку */ + if (not PRSG_CALCTAB_STORE.NEXT_ROW(RCURSOR => RCURSOR)) then + exit; + end if; + end loop; + end if; + end STAGE_ARTS_GET; + + /* Список статей калькуляции этапа проекта */ + procedure STAGE_ARTS_LIST + ( + NSTAGE in number, -- Рег. номер этапа проекта + CFILTERS in clob, -- Фильтры + NINCLUDE_DEF in number, -- Признак включения описания колонок таблицы в ответ + COUT out clob -- Сериализованная таблица данных + ) + is + RF PKG_P8PANELS_VISUAL.TFILTERS; -- Фильтры + RF_CTRL_COST PKG_P8PANELS_VISUAL.TFILTER; -- Фильтр по колонке "Контроль (затраты)" + NCTRL_COST_FROM PKG_STD.TNUMBER; -- Нижняя граница диапазона фильтра по колонке "Контроль (затраты)" + NCTRL_COST_TO PKG_STD.TNUMBER; -- Верхняя граница диапазона фильтра по колонке "Контроль (затраты)" + RF_CTRL_CONTR PKG_P8PANELS_VISUAL.TFILTER; -- Фильтр по колонке "Контроль (контрактация)" + NCTRL_CONTR_FROM PKG_STD.TNUMBER; -- Нижняя граница диапазона фильтра по колонке "Контроль (контрактация)" + NCTRL_CONTR_TO PKG_STD.TNUMBER; -- Верхняя граница диапазона фильтра по колонке "Контроль (контрактация)" + RDG PKG_P8PANELS_VISUAL.TDATA_GRID; -- Описание таблицы + RDG_ROW PKG_P8PANELS_VISUAL.TROW; -- Строка таблицы + RCOL_VALS PKG_P8PANELS_VISUAL.TCOL_VALS; -- Предопределённые значения столбцов + RSTAGE_ARTS TSTAGE_ARTS; -- Список статей этапа проекта + begin + /* Читаем фильтры */ + RF := PKG_P8PANELS_VISUAL.TFILTERS_FROM_XML(CFILTERS => CFILTERS); + /* Найдем фильтр по контролю затрат */ + RF_CTRL_COST := PKG_P8PANELS_VISUAL.TFILTERS_FIND(RFILTERS => RF, SNAME => 'NCTRL_COST'); + PKG_P8PANELS_VISUAL.TFILTER_TO_NUMBER(RFILTER => RF_CTRL_COST, NFROM => NCTRL_COST_FROM, NTO => NCTRL_COST_TO); + /* Найдем фильтр по контролю контрактации */ + RF_CTRL_CONTR := PKG_P8PANELS_VISUAL.TFILTERS_FIND(RFILTERS => RF, SNAME => 'NCTRL_CONTR'); + PKG_P8PANELS_VISUAL.TFILTER_TO_NUMBER(RFILTER => RF_CTRL_CONTR, NFROM => NCTRL_CONTR_FROM, NTO => NCTRL_CONTR_TO); + /* Инициализируем таблицу данных */ + 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 => 'SNUMB', + SCAPTION => 'Номер', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'SNAME', + SCAPTION => 'Наименование статьи', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NPLAN', + SCAPTION => 'План', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NCOST_FACT', + SCAPTION => 'Фактические затраты', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NCOST_DIFF', + SCAPTION => 'Отклонение по затратам', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 0, BCLEAR => true); + PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 1); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NCTRL_COST', + SCAPTION => 'Контроль (затраты)', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, + BFILTER => true, + RCOL_VALS => RCOL_VALS); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NCONTR', + SCAPTION => 'Законтрактовано', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NCONTR_LEFT', + SCAPTION => 'Осталось законтрактовать', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NCTRL_CONTR', + SCAPTION => 'Контроль (контрактация)', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, + BFILTER => true, + RCOL_VALS => RCOL_VALS); + /* Сформируем сведения по статям этапа проекта */ + STAGE_ARTS_GET(NSTAGE => NSTAGE, NINC_COST => 1, NINC_CONTR => 1, RSTAGE_ARTS => RSTAGE_ARTS); + /* Обходим собранные статьи */ + if ((RSTAGE_ARTS is not null) and (RSTAGE_ARTS.COUNT > 0)) then + for I in RSTAGE_ARTS.FIRST .. RSTAGE_ARTS.LAST + loop + /* Если прошли фильтр */ + if (((NCTRL_COST_FROM is null) or + ((NCTRL_COST_FROM is not null) and (NCTRL_COST_FROM = RSTAGE_ARTS(I).NCTRL_COST))) and + ((NCTRL_CONTR_FROM is null) or + ((NCTRL_CONTR_FROM is not null) and (NCTRL_CONTR_FROM = RSTAGE_ARTS(I).NCTRL_CONTR)))) then + /* Добавляем колонки с данными */ + PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, + SNAME => 'NRN', + NVALUE => RSTAGE_ARTS(I).NRN, + BCLEAR => true); + PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SNUMB', SVALUE => RSTAGE_ARTS(I).SCODE); + PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SNAME', SVALUE => RSTAGE_ARTS(I).SNAME); + PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NPLAN', NVALUE => RSTAGE_ARTS(I).NPLAN); + PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NCOST_FACT', NVALUE => RSTAGE_ARTS(I).NCOST_FACT); + PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NCOST_DIFF', NVALUE => RSTAGE_ARTS(I).NCOST_DIFF); + PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NCTRL_COST', NVALUE => RSTAGE_ARTS(I).NCTRL_COST); + PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NCONTR', NVALUE => RSTAGE_ARTS(I).NCONTR); + PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, + SNAME => 'NCONTR_LEFT', + NVALUE => RSTAGE_ARTS(I).NCONTR_LEFT); + PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, + SNAME => 'NCTRL_CONTR', + NVALUE => RSTAGE_ARTS(I).NCTRL_CONTR); + /* Добавляем строку в таблицу */ + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW); + end if; + end loop; + end if; + /* Сериализуем описание */ + COUT := PKG_P8PANELS_VISUAL.TDATA_GRID_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => NINCLUDE_DEF); + end STAGE_ARTS_LIST; + + /* Список договоров этапа проекта */ + procedure STAGE_CONTRACTS_COND + is + begin + /* Установка главной таблицы */ + PKG_COND_BROKER.SET_TABLE(STABLE_NAME => 'PROJECTSTAGEPF'); + /* Этап проекта */ + PKG_COND_BROKER.SET_COLUMN_PRN(SCOLUMN_NAME => 'PRN'); + /* Соисполнитель */ + PKG_COND_BROKER.ADD_CONDITION_CODE(SCOLUMN_NAME => 'AGNNAME', + SCONDITION_NAME => 'EDAGENT', + SJOINS => 'PERFORMER <- RN;AGNLIST'); + /* Статья затрат */ + PKG_COND_BROKER.ADD_CONDITION_CODE(SCOLUMN_NAME => 'CODE', + SCONDITION_NAME => 'EDSCOST_ART', + SJOINS => 'COST_ARTICLE <- RN;FPDARTCL'); + /* Группа - этап договора */ + PKG_COND_BROKER.SET_GROUP(SGROUP_NAME => 'STAGES', + STABLE_NAME => 'STAGES', + SCOLUMN_NAME => 'FACEACC', + SPARENT_COLUMN_NAME => 'FACEACC'); + /* Этап договора - номер этапа */ + PKG_COND_BROKER.ADD_GROUP_CONDITION_CODE(SGROUP_NAME => 'STAGES', + SCOLUMN_NAME => 'NUMB', + SCONDITION_NAME => 'EDSTAGE', + IALIGN => 20); + /* Этап договора - дата начала этапа */ + PKG_COND_BROKER.ADD_GROUP_CONDITION_BETWEEN(SGROUP_NAME => 'STAGES', + SCOLUMN_NAME => 'BEGIN_DATE', + SCONDITION_NAME_FROM => 'EDCSTAGE_BEGIN_DATEFrom', + SCONDITION_NAME_TO => 'EDCSTAGE_BEGIN_DATETo'); + /* Этап договора - дата окончания этапа */ + PKG_COND_BROKER.ADD_GROUP_CONDITION_BETWEEN(SGROUP_NAME => 'STAGES', + SCOLUMN_NAME => 'END_DATE', + SCONDITION_NAME_FROM => 'EDCSTAGE_END_DATEFrom', + SCONDITION_NAME_TO => 'EDCSTAGE_END_DATETo'); + /* Этап договора - префикс договора */ + PKG_COND_BROKER.ADD_GROUP_CONDITION_CODE(SGROUP_NAME => 'STAGES', + SCOLUMN_NAME => 'DOC_PREF', + SCONDITION_NAME => 'EDDOC_PREF', + SJOINS => 'PRN <- RN;CONTRACTS', + IALIGN => 80); + /* Этап договора - номер договора */ + PKG_COND_BROKER.ADD_GROUP_CONDITION_CODE(SGROUP_NAME => 'STAGES', + SCOLUMN_NAME => 'DOC_NUMB', + SCONDITION_NAME => 'EDDOC_NUMB', + SJOINS => 'PRN <- RN;CONTRACTS', + IALIGN => 80); + /* Этап договора - дата договора */ + PKG_COND_BROKER.ADD_GROUP_CONDITION_BETWEEN(SGROUP_NAME => 'STAGES', + SCOLUMN_NAME => 'DOC_DATE', + SCONDITION_NAME_FROM => 'EDDOC_DATEFrom', + SCONDITION_NAME_TO => 'EDDOC_DATETo', + SJOINS => 'PRN <- RN;CONTRACTS'); + end STAGE_CONTRACTS_COND; + + /* Список договоров этапа проекта */ + procedure STAGE_CONTRACTS_LIST + ( + NSTAGE in number, -- Рег. номер этапа проекта + NPAGE_NUMBER in number, -- Номер страницы (игнорируется при NPAGE_SIZE=0) + NPAGE_SIZE in number, -- Количество записей на странице (0 - все) + CFILTERS in clob, -- Фильтры + CORDERS in clob, -- Сортировки + NINCLUDE_DEF in number, -- Признак включения описания колонок таблицы в ответ + COUT out clob -- Сериализованная таблица данных + ) + is + NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса + NIDENT PKG_STD.TREF := GEN_IDENT(); -- Идентификатор отбора + RF PKG_P8PANELS_VISUAL.TFILTERS; -- Фильтры + RO PKG_P8PANELS_VISUAL.TORDERS; -- Сортировки + RDG PKG_P8PANELS_VISUAL.TDATA_GRID; -- Описание таблицы + RDG_ROW PKG_P8PANELS_VISUAL.TROW; -- Строка таблицы + NROW_FROM PKG_STD.TREF; -- Номер строки с + NROW_TO PKG_STD.TREF; -- Номер строки по + CSQL clob; -- Буфер для запроса + ICURSOR integer; -- Курсор для исполнения запроса + begin + /* Читаем фильтры */ + RF := PKG_P8PANELS_VISUAL.TFILTERS_FROM_XML(CFILTERS => CFILTERS); + /* Читем сортировки */ + RO := PKG_P8PANELS_VISUAL.TORDERS_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.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 => 'SDOC_PREF', + SCAPTION => 'Префикс', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + SCOND_FROM => 'EDDOC_PREF', + BORDER => true, + BFILTER => true); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'SLNK_UNIT_SDOC_PREF', + SCAPTION => 'Префикс (код раздела ссылки)', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NLNK_DOCUMENT_SDOC_PREF', + SCAPTION => 'Префикс (документ ссылки)', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'SDOC_NUMB', + SCAPTION => 'Номер', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + SCOND_FROM => 'EDDOC_NUMB', + BORDER => true, + BFILTER => true); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'SLNK_UNIT_SDOC_NUMB', + SCAPTION => 'Номер (код раздела ссылки)', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NLNK_DOCUMENT_SDOC_NUMB', + SCAPTION => 'Номер (документ ссылки)', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'DDOC_DATE', + SCAPTION => 'Дата', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_DATE, + SCOND_FROM => 'EDDOC_DATEFrom', + SCOND_TO => 'EDDOC_DATETo', + BORDER => true, + BFILTER => true); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'SEXT_NUMBER', + SCAPTION => 'Внешний номер', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'SAGENT', + SCAPTION => 'Соисполнитель', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + SCOND_FROM => 'EDAGENT', + BORDER => true, + BFILTER => true); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'SAGENT_INN', + SCAPTION => 'ИНН соисполнителя', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'SAGENT_KPP', + SCAPTION => 'КПП соисполнителя', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'SGOVCNTRID', + SCAPTION => 'ИГК', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'SCSTAGE', + SCAPTION => 'Этап', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + SCOND_FROM => 'EDSTAGE', + BORDER => true, + BFILTER => true); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'SCSTAGE_DESCRIPTION', + SCAPTION => 'Описание этапа', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'DCSTAGE_BEGIN_DATE', + SCAPTION => 'Дата начала', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_DATE, + SCOND_FROM => 'EDCSTAGE_BEGIN_DATEFrom', + SCOND_TO => 'EDCSTAGE_BEGIN_DATETo', + BORDER => true, + BFILTER => true); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'DCSTAGE_END_DATE', + SCAPTION => 'Дата окончания', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_DATE, + SCOND_FROM => 'EDCSTAGE_END_DATEFrom', + SCOND_TO => 'EDCSTAGE_END_DATETo', + BORDER => true, + BFILTER => true); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'NSUMM', + SCAPTION => 'Сумма', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'SCURR', + SCAPTION => 'Валюта', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'SCOST_ART', + SCAPTION => 'Статья затрат', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + SCOND_FROM => 'EDSCOST_ART', + BORDER => true, + BFILTER => true); + /* Обходим данные */ + begin + /* Собираем запрос */ + CSQL := 'select * + from (select D.*, + ROWNUM NROW + from (select PSPF.RN NRN, + trim(CN.DOC_PREF) SDOC_PREF, + ''Contracts'' SLNK_UNIT_SDOC_PREF, + CN.RN NLNK_DOCUMENT_SDOC_PREF, + trim(CN.DOC_NUMB) SDOC_NUMB, + ''Contracts'' SLNK_UNIT_SDOC_NUMB, + CN.RN NLNK_DOCUMENT_SDOC_NUMB, + CN.DOC_DATE DDOC_DATE, + CN.EXT_NUMBER SEXT_NUMBER, + AG.AGNNAME SAGENT, + AG.AGNIDNUMB SAGENT_INN, + AG.REASON_CODE SAGENT_KPP, + ''"'' || GC.CODE || ''"'' SGOVCNTRID, + trim(ST.NUMB) SCSTAGE, + ST.DESCRIPTION SCSTAGE_DESCRIPTION, + ST.BEGIN_DATE DCSTAGE_BEGIN_DATE, + ST.END_DATE DCSTAGE_END_DATE, + PSPF.COST_PLAN NSUMM, + CUR.INTCODE SCURR, + ART.CODE SCOST_ART + from PROJECTSTAGEPF PSPF, + STAGES ST, + CONTRACTS CN, + AGNLIST AG, + CURNAMES CUR, + FPDARTCL ART, + GOVCNTRID GC + where PSPF.FACEACC = ST.FACEACC + and ST.PRN = CN.RN + and PSPF.PERFORMER = AG.RN + and CN.CURRENCY = CUR.RN + and PSPF.COST_ARTICLE = ART.RN(+) + and CN.GOVCNTRID = GC.RN(+) + and PSPF.RN in (select ID from COND_BROKER_IDSMART where IDENT = :NIDENT) %ORDER_BY%) D) F + where F.NROW between :NROW_FROM and :NROW_TO'; + /* Учтём сортировки */ + PKG_P8PANELS_VISUAL.TORDERS_SET_QUERY(RDATA_GRID => RDG, RORDERS => RO, SPATTERN => '%ORDER_BY%', CSQL => CSQL); + /* Учтём фильтры */ + PKG_P8PANELS_VISUAL.TFILTERS_SET_QUERY(NIDENT => NIDENT, + NCOMPANY => NCOMPANY, + NPARENT => NSTAGE, + SUNIT => 'ProjectsStagesPerformers', + SPROCEDURE => 'PKG_P8PANELS_PROJECTS.STAGE_CONTRACTS_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_NUM(ICURSOR => ICURSOR, IPOSITION => 1); + PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 2); + PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 3); + PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 4); + PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 5); + PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 6); + PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 7); + PKG_SQL_DML.DEFINE_COLUMN_DATE(ICURSOR => ICURSOR, IPOSITION => 8); + PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 9); + PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 10); + PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 11); + PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 12); + PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 13); + PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 14); + PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 15); + PKG_SQL_DML.DEFINE_COLUMN_DATE(ICURSOR => ICURSOR, IPOSITION => 16); + PKG_SQL_DML.DEFINE_COLUMN_DATE(ICURSOR => ICURSOR, IPOSITION => 17); + PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 18); + PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 19); + PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 20); + /* Делаем выборку */ + if (PKG_SQL_DML.EXECUTE(ICURSOR => ICURSOR) = 0) then + null; + end if; + /* Обходим выбранные записи */ + while (PKG_SQL_DML.FETCH_ROWS(ICURSOR => ICURSOR) > 0) + loop + /* Добавляем колонки с данными */ + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, + SNAME => 'NRN', + ICURSOR => ICURSOR, + NPOSITION => 1, + BCLEAR => true); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, + SNAME => 'SDOC_PREF', + ICURSOR => ICURSOR, + NPOSITION => 2); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, + SNAME => 'SLNK_UNIT_SDOC_PREF', + ICURSOR => ICURSOR, + NPOSITION => 3); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, + SNAME => 'NLNK_DOCUMENT_SDOC_PREF', + ICURSOR => ICURSOR, + NPOSITION => 4); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, + SNAME => 'SDOC_NUMB', + ICURSOR => ICURSOR, + NPOSITION => 5); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, + SNAME => 'SLNK_UNIT_SDOC_NUMB', + ICURSOR => ICURSOR, + NPOSITION => 6); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, + SNAME => 'NLNK_DOCUMENT_SDOC_NUMB', + ICURSOR => ICURSOR, + NPOSITION => 7); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLD(RROW => RDG_ROW, + SNAME => 'DDOC_DATE', + ICURSOR => ICURSOR, + NPOSITION => 8); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, + SNAME => 'SEXT_NUMBER', + ICURSOR => ICURSOR, + NPOSITION => 9); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SAGENT', ICURSOR => ICURSOR, NPOSITION => 10); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, + SNAME => 'SAGENT_INN', + ICURSOR => ICURSOR, + NPOSITION => 11); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, + SNAME => 'SAGENT_KPP', + ICURSOR => ICURSOR, + NPOSITION => 12); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, + SNAME => 'SGOVCNTRID', + ICURSOR => ICURSOR, + NPOSITION => 13); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SCSTAGE', ICURSOR => ICURSOR, NPOSITION => 14); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, + SNAME => 'SCSTAGE_DESCRIPTION', + ICURSOR => ICURSOR, + NPOSITION => 15); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLD(RROW => RDG_ROW, + SNAME => 'DCSTAGE_BEGIN_DATE', + ICURSOR => ICURSOR, + NPOSITION => 16); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLD(RROW => RDG_ROW, + SNAME => 'DCSTAGE_END_DATE', + ICURSOR => ICURSOR, + NPOSITION => 17); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NSUMM', ICURSOR => ICURSOR, NPOSITION => 18); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SCURR', ICURSOR => ICURSOR, NPOSITION => 19); + PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, + SNAME => 'SCOST_ART', + ICURSOR => ICURSOR, + NPOSITION => 20); + /* Добавляем строку в таблицу */ + PKG_P8PANELS_VISUAL.TDATA_GRID_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.TDATA_GRID_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => NINCLUDE_DEF); + end STAGE_CONTRACTS_LIST; + +end PKG_P8PANELS_PROJECTS; +/ diff --git a/db/PKG_P8PANELS_VISUAL.pck b/db/PKG_P8PANELS_VISUAL.pck new file mode 100644 index 0000000..f5689e9 --- /dev/null +++ b/db/PKG_P8PANELS_VISUAL.pck @@ -0,0 +1,1131 @@ +create or replace package PKG_P8PANELS_VISUAL as + + /* Константы - типы данных */ + SDATA_TYPE_STR constant PKG_STD.TSTRING := 'STR'; -- Тип данных "строка" + SDATA_TYPE_NUMB constant PKG_STD.TSTRING := 'NUMB'; -- Тип данных "число" + SDATA_TYPE_DATE constant PKG_STD.TSTRING := 'DATE'; -- Тип данных "дата" + + /* Константы - направление сортировки */ + SORDER_DIRECTION_ASC constant PKG_STD.TSTRING := 'ASC'; -- По возрастанию + SORDER_DIRECTION_DESC constant PKG_STD.TSTRING := 'DESC'; -- По убыванию + + /* Типы данных - значение колонки таблицы данных */ + type TCOL_VAL is record + ( + SVALUE PKG_STD.TLSTRING, -- Значение (строка) + NVALUE PKG_STD.TNUMBER, -- Значение (число) + DVALUE PKG_STD.TLDATE -- Значение (дата) + ); + + /* Типы данных - коллекция значений колонки таблицы данных */ + type TCOL_VALS is table of TCOL_VAL; + + /* Типы данных - описатель колонки таблицы данных */ + type TCOL_DEF is record + ( + SNAME PKG_STD.TSTRING, -- Наименование + SCAPTION PKG_STD.TSTRING, -- Заголовок + SDATA_TYPE PKG_STD.TSTRING, -- Тип данных (см. константы SDATA_TYPE_*) + SCOND_FROM PKG_STD.TSTRING, -- Наименование нижней границы условия отбора + SCOND_TO PKG_STD.TSTRING, -- Наименование верхней границы условия отбора + BVISIBLE boolean, -- Разрешить отображение + BORDER boolean, -- Разрешить сортировку + BFILTER boolean, -- Разрешить отбор + RCOL_VALS TCOL_VALS -- Предопределённые значения + ); + + /* Типы данных - коллекция описателей колонок таблицы данных */ + type TCOL_DEFS is table of TCOL_DEF; + + /* Типы данных - колонка */ + type TCOL is record + ( + SNAME PKG_STD.TSTRING, -- Наименование + RCOL_VAL TCOL_VAL -- Значение + ); + + /* Типы данных - коллекция колонок */ + type TCOLS is table of TCOL; + + /* Типы данных - строка */ + type TROW is record + ( + RCOLS TCOLS -- Колонки + ); + + /* Типы данных - коллекция строк */ + type TROWS is table of TROW; + + /* Типы данных - таблица данных */ + type TDATA_GRID is record + ( + RCOL_DEFS TCOL_DEFS, -- Описание колонок + RROWS TROWS -- Данные строк + ); + + /* Типы данных - фильтр */ + type TFILTER is record + ( + SNAME PKG_STD.TSTRING, -- Наименование + SFROM PKG_STD.TSTRING, -- Значение "с" + STO PKG_STD.TSTRING -- Значение "по" + ); + + /* Типы данных - коллекция фильтров */ + type TFILTERS is table of TFILTER; + + /* Типы данных - сортировка */ + type TORDER is record + ( + SNAME PKG_STD.TSTRING, -- Наименование + SDIRECTION PKG_STD.TSTRING -- Направление (см. константы SORDER_DIRECTION_*) + ); + + /* Типы данных - коллекция сортировок */ + type TORDERS is table of TORDER; + + /* Расчет диапаона выдаваемых записей */ + procedure UTL_ROWS_LIMITS_CALC + ( + NPAGE_NUMBER in number, -- Номер страницы (игнорируется при NPAGE_SIZE=0) + NPAGE_SIZE in number, -- Количество записей на странице (0 - все) + NROW_FROM out number, -- Нижняя граница диапазона + NROW_TO out number -- Верхняя граница диапазона + ); + + /* Формирование наименования условия отбора для нижней границы */ + function UTL_COND_NAME_MAKE_FROM + ( + SNAME in varchar2 -- Наименование колонки + ) return varchar2; -- Результат + + /* Формирование наименования условия отбора для верхней границы */ + function UTL_COND_NAME_MAKE_TO + ( + SNAME in varchar2 -- Наименование колонки + ) return varchar2; -- Результат + + /* Добавление значения в коллекцию */ + procedure TCOL_VALS_ADD + ( + RCOL_VALS in out nocopy TCOL_VALS, -- Коллекция значений + SVALUE in varchar2 := null, -- Значение (строка) + NVALUE in number := null, -- Значение (число) + DVALUE in date := null, -- Значение (дата) + BCLEAR in boolean := false -- Флаг очистки коллекции (false - не очищать, true - очистить коллекцию перед добавлением) + ); + + /* Формирование строки */ + function TROW_MAKE + return TROW; -- Результат работы + + /* Добавление колонки к строке */ + procedure TROW_ADD_COL + ( + RROW in out nocopy TROW, -- Строка + SNAME in varchar2, -- Наименование колонки + SVALUE in varchar2 := null, -- Значение (строка) + NVALUE in number := null, -- Значение (число) + DVALUE in date := null, -- Значение (дата) + BCLEAR in boolean := false -- Флаг очистки коллекции (false - не очищать, true - очистить коллекцию перед добавлением) + ); + + /* Добавление строковой колонки к строке из курсора динамического запроса */ + procedure TROW_ADD_CUR_COLS + ( + RROW in out nocopy TROW, -- Строка + SNAME in varchar2, -- Наименование колонки + ICURSOR in integer, -- Курсор + NPOSITION in number, -- Номер колонки в курсоре + BCLEAR in boolean := false -- Флаг очистки коллекции (false - не очищать, true - очистить коллекцию перед добавлением) + ); + + /* Добавление числовой колонки к строке из курсора динамического запроса */ + procedure TROW_ADD_CUR_COLN + ( + RROW in out nocopy TROW, -- Строка + SNAME in varchar2, -- Наименование колонки + ICURSOR in integer, -- Курсор + NPOSITION in number, -- Номер колонки в курсоре + BCLEAR in boolean := false -- Флаг очистки коллекции (false - не очищать, true - очистить коллекцию перед добавлением) + ); + + /* Добавление колонки типа "дата" к строке из курсора динамического запроса */ + procedure TROW_ADD_CUR_COLD + ( + RROW in out nocopy TROW, -- Строка + SNAME in varchar2, -- Наименование колонки + ICURSOR in integer, -- Курсор + NPOSITION in number, -- Номер колонки в курсоре + BCLEAR in boolean := false -- Флаг очистки коллекции (false - не очищать, true - очистить коллекцию перед добавлением) + ); + + /* Формирование таблицы данныз */ + function TDATA_GRID_MAKE + return TDATA_GRID; -- Результат работы + + /* Поиск описания колонки в таблице данных по наименованию */ + function TDATA_GRID_FIND_COL_DEF + ( + RDATA_GRID in TDATA_GRID, -- Описание таблицы данных + SNAME in varchar2 -- Наименование колонки + ) return TCOL_DEF; -- Найденное описание (null - если не нашли) + + /* Добавление описания колонки к таблице данных */ + procedure TDATA_GRID_ADD_COL_DEF + ( + RDATA_GRID in out nocopy TDATA_GRID, -- Описание таблицы данных + SNAME in varchar2, -- Наименование колонки + SCAPTION in varchar2, -- Заголовок колонки + SDATA_TYPE in varchar2 := SDATA_TYPE_STR, -- Тип данных колонки (см. константы SDATA_TYPE_*) + SCOND_FROM in varchar2 := null, -- Наименование нижней границы условия отбора (null - используется UTL_COND_NAME_MAKE_FROM) + SCOND_TO in varchar2 := null, -- Наименование верхней границы условия отбора (null - используется UTL_COND_NAME_MAKE_TO) + BVISIBLE in boolean := true, -- Разрешить отображение + BORDER in boolean := false, -- Разрешить сортировку по колонке + BFILTER in boolean := false, -- Разрешить отбор по колонке + RCOL_VALS in TCOL_VALS := null, -- Предопределённые значения колонки + BCLEAR in boolean := false -- Флаг очистки коллекции описаний колонок таблицы данных (false - не очищать, true - очистить коллекцию перед добавлением) + ); + + /* Добавление описания колонки к таблице данных */ + procedure TDATA_GRID_ADD_ROW + ( + RDATA_GRID in out nocopy TDATA_GRID, -- Описание таблицы данных + RROW in TROW, -- Строка + BCLEAR in boolean := false -- Флаг очистки коллекции строк таблицы данных (false - не очищать, true - очистить коллекцию перед добавлением) + ); + + /* Сериализация таблицы данных */ + function TDATA_GRID_TO_XML + ( + RDATA_GRID in TDATA_GRID, -- Описание таблицы данных + NINCLUDE_DEF in number := 1 -- Включить описание колонок (0 - нет, 1 - да) + ) return clob; -- XML-описание + + + /* Конвертация значений фильтра в число */ + procedure TFILTER_TO_NUMBER + ( + RFILTER in TFILTER, -- Фильтр + NFROM out number, -- Значение нижней границы диапазона + NTO out number -- Значение верхней границы диапазона + ); + + /* Конвертация значений фильтра в дату */ + procedure TFILTER_TO_DATE + ( + RFILTER in TFILTER, -- Фильтр + DFROM out date, -- Значение нижней границы диапазона + DTO out date -- Значение верхней границы диапазона + ); + + /* Поиск фильтра в коллекции */ + function TFILTERS_FIND + ( + RFILTERS in TFILTERS, -- Коллекция фильтров + SNAME in varchar2 -- Наименование + ) return TFILTER; -- Найденный фильтр (null - если не нашли) + + /* Десериализация фильтров */ + function TFILTERS_FROM_XML + ( + CFILTERS in clob -- Сериализованное представление фильтров (BASE64(ИМЯЗНАЧЕНИЕЗНАЧЕНИЕ...)) + ) return TFILTERS; -- Результат работы + + /* Применение параметров фильтрации в запросе */ + procedure TFILTERS_SET_QUERY + ( + NIDENT in number, -- Идентификатор отбора + NCOMPANY in number, -- Рег. номер организации + NPARENT in number := null, -- Рег. номер родителя + SUNIT in varchar2, -- Код раздела + SPROCEDURE in varchar2, -- Наименование серверной процедуры отбора + RDATA_GRID in TDATA_GRID, -- Описание таблицы данных + RFILTERS in TFILTERS -- Коллекция фильтров + ); + + /* Десериализация сортировок */ + function TORDERS_FROM_XML + ( + CORDERS in clob -- Сериализованное представление сотрировок (BASE64(ИМЯASC/DESC...)) + ) return TORDERS; -- Результат работы + + /* Применение параметров сортировки в запросе */ + procedure TORDERS_SET_QUERY + ( + RDATA_GRID in TDATA_GRID, -- Описание таблицы + RORDERS in TORDERS, -- Коллекция сортировок + SPATTERN in varchar2, -- Шаблон для подстановки условий отбора в запрос + CSQL in out nocopy clob -- Буфер запроса + ); + +end PKG_P8PANELS_VISUAL; +/ +create or replace package body PKG_P8PANELS_VISUAL as + + /* Константы - тэги запросов */ + SRQ_TAG_XROOT constant PKG_STD.TSTRING := 'XROOT'; -- Тэг для корня данных запроса + SRQ_TAG_XFILTERS constant PKG_STD.TSTRING := 'filters'; -- Тэг для строк данных + SRQ_TAG_XORDERS constant PKG_STD.TSTRING := 'orders'; -- Тэг для описания колонок + SRQ_TAG_SNAME constant PKG_STD.TSTRING := 'name'; -- Тэг для наименования + SRQ_TAG_SDIRECTION constant PKG_STD.TSTRING := 'direction'; -- Тэг для направления + SRQ_TAG_SFROM constant PKG_STD.TSTRING := 'from'; -- Тэг для значения "с" + SRQ_TAG_STO constant PKG_STD.TSTRING := 'to'; -- Тэг для значения "по" + + /* Константы - тэги ответов */ + SRESP_TAG_XDATA constant PKG_STD.TSTRING := 'XDATA'; -- Тэг для корня описания данных + SRESP_TAG_XROWS constant PKG_STD.TSTRING := 'XROWS'; -- Тэг для строк данных + SRESP_TAG_XCOLUMNS_DEF constant PKG_STD.TSTRING := 'XCOLUMNS_DEF'; -- Тэг для описания колонок + + /* Константы - атрибуты ответов */ + SRESP_ATTR_NAME constant PKG_STD.TSTRING := 'name'; -- Атрибут для наименования + SRESP_ATTR_CAPTION constant PKG_STD.TSTRING := 'caption'; -- Атрибут для подписи + SRESP_ATTR_DATA_TYPE constant PKG_STD.TSTRING := 'dataType'; -- Атрибут для типа данных + SRESP_ATTR_VISIBLE constant PKG_STD.TSTRING := 'visible'; -- Атрибут для флага видимости + SRESP_ATTR_ORDER constant PKG_STD.TSTRING := 'order'; -- Атрибут для флага сортировки + SRESP_ATTR_FILTER constant PKG_STD.TSTRING := 'filter'; -- Атрибут для флага отбора + SRESP_ATTR_VALUES constant PKG_STD.TSTRING := 'values'; -- Атрибут для значений + + /* Константы - параметры условий отбора */ + SCOND_FROM_POSTFIX constant PKG_STD.TSTRING := 'From'; -- Постфикс наименования нижней границы условия отбора + SCOND_TO_POSTFIX constant PKG_STD.TSTRING := 'To'; -- Постфикс наименования верхней границы условия отбора + + /* Расчет диапаона выдаваемых записей */ + procedure UTL_ROWS_LIMITS_CALC + ( + NPAGE_NUMBER in number, -- Номер страницы (игнорируется при NPAGE_SIZE=0) + NPAGE_SIZE in number, -- Количество записей на странице (0 - все) + NROW_FROM out number, -- Нижняя граница диапазона + NROW_TO out number -- Верхняя граница диапазона + ) + is + begin + if (COALESCE(NPAGE_SIZE, 0) <= 0) + then + NROW_FROM := 1; + NROW_TO := 1000000000; + else + NROW_FROM := COALESCE(NPAGE_NUMBER, 1) * NPAGE_SIZE - NPAGE_SIZE + 1; + NROW_TO := COALESCE(NPAGE_NUMBER, 1) * NPAGE_SIZE; + end if; + end UTL_ROWS_LIMITS_CALC; + + /* Формирование наименования условия отбора для нижней границы */ + function UTL_COND_NAME_MAKE_FROM + ( + SNAME in varchar2 -- Наименование колонки + ) return varchar2 -- Результат + is + begin + return SNAME || SCOND_FROM_POSTFIX; + end UTL_COND_NAME_MAKE_FROM; + + /* Формирование наименования условия отбора для верхней границы */ + function UTL_COND_NAME_MAKE_TO + ( + SNAME in varchar2 -- Наименование колонки + ) return varchar2 -- Результат + is + begin + return SNAME || SCOND_TO_POSTFIX; + end UTL_COND_NAME_MAKE_TO; + + /* Формирование значения */ + function TCOL_VAL_MAKE + ( + SVALUE in varchar2, -- Значение (строка) + NVALUE in number, -- Значение (число) + DVALUE in date -- Значение (дата) + ) return TCOL_VAL -- Результат работы + is + RRES TCOL_VAL; -- Буфер для результата + begin + /* Формируем объект */ + RRES.SVALUE := SVALUE; + RRES.NVALUE := NVALUE; + RRES.DVALUE := DVALUE; + /* Возвращаем результат */ + return RRES; + end TCOL_VAL_MAKE; + + /* Добавление значения в коллекцию */ + procedure TCOL_VALS_ADD + ( + RCOL_VALS in out nocopy TCOL_VALS, -- Коллекция значений + SVALUE in varchar2 := null, -- Значение (строка) + NVALUE in number := null, -- Значение (число) + DVALUE in date := null, -- Значение (дата) + BCLEAR in boolean := false -- Флаг очистки коллекции (false - не очищать, true - очистить коллекцию перед добавлением) + ) + is + begin + /* Инициализируем коллекцию если необходимо */ + if ((RCOL_VALS is null) or (BCLEAR)) then + RCOL_VALS := TCOL_VALS(); + end if; + /* Добавляем элемент */ + RCOL_VALS.EXTEND(); + RCOL_VALS(RCOL_VALS.LAST) := TCOL_VAL_MAKE(SVALUE => SVALUE, NVALUE => NVALUE, DVALUE => DVALUE); + end TCOL_VALS_ADD; + + /* Формирование описания колонки */ + function TCOL_DEF_MAKE + ( + SNAME in varchar2, -- Наименование + SCAPTION in varchar2, -- Заголовок + SDATA_TYPE in varchar2 := SDATA_TYPE_STR, -- Тип данных (см. константы SDATA_TYPE_*) + SCOND_FROM in varchar2 := null, -- Наименование нижней границы условия отбора (null - используется UTL_COND_NAME_MAKE_FROM) + SCOND_TO in varchar2 := null, -- Наименование верхней границы условия отбора (null - используется UTL_COND_NAME_MAKE_TO) + BVISIBLE in boolean := true, -- Разрешить отображение + BORDER in boolean := false, -- Разрешить сортировку + BFILTER in boolean := false, -- Разрешить отбор + RCOL_VALS in TCOL_VALS := null -- Предопределённые значения + ) return TCOL_DEF -- Результат работы + is + RRES TCOL_DEF; -- Буфер для результата + begin + /* Формируем объект */ + RRES.SNAME := SNAME; + RRES.SCAPTION := SCAPTION; + RRES.SDATA_TYPE := COALESCE(SDATA_TYPE, SDATA_TYPE_STR); + RRES.SCOND_FROM := COALESCE(SCOND_FROM, UTL_COND_NAME_MAKE_FROM(SNAME => SNAME)); + RRES.SCOND_TO := COALESCE(SCOND_TO, UTL_COND_NAME_MAKE_TO(SNAME => SNAME)); + RRES.BVISIBLE := COALESCE(BVISIBLE, true); + RRES.BORDER := COALESCE(BORDER, false); + RRES.BFILTER := COALESCE(BFILTER, false); + RRES.RCOL_VALS := COALESCE(RCOL_VALS, TCOL_VALS()); + /* Возвращаем результат */ + return RRES; + end TCOL_DEF_MAKE; + + /* Добавление описания колонки в коллекцию */ + procedure TCOL_DEFS_ADD + ( + RCOL_DEFS in out nocopy TCOL_DEFS, -- Коллекция описаний колонок + SNAME in varchar2, -- Наименование + SCAPTION in varchar2, -- Заголовок + SDATA_TYPE in varchar2 := SDATA_TYPE_STR, -- Тип данных (см. константы SDATA_TYPE_*) + SCOND_FROM in varchar2 := null, -- Наименование нижней границы условия отбора (null - используется UTL_COND_NAME_MAKE_FROM) + SCOND_TO in varchar2 := null, -- Наименование верхней границы условия отбора (null - используется UTL_COND_NAME_MAKE_TO) + BVISIBLE in boolean := true, -- Разрешить отображение + BORDER in boolean := false, -- Разрешить сортировку + BFILTER in boolean := false, -- Разрешить отбор + RCOL_VALS in TCOL_VALS := null, -- Предопределённые значения + BCLEAR in boolean := false -- Флаг очистки коллекции (false - не очищать, true - очистить коллекцию перед добавлением) + ) + is + begin + /* Инициализируем коллекцию если необходимо */ + if ((RCOL_DEFS is null) or (BCLEAR)) then + RCOL_DEFS := TCOL_DEFS(); + end if; + /* Добавляем элемент */ + RCOL_DEFS.EXTEND(); + RCOL_DEFS(RCOL_DEFS.LAST) := TCOL_DEF_MAKE(SNAME => SNAME, + SCAPTION => SCAPTION, + SDATA_TYPE => SDATA_TYPE, + SCOND_FROM => SCOND_FROM, + SCOND_TO => SCOND_TO, + BVISIBLE => BVISIBLE, + BORDER => BORDER, + BFILTER => BFILTER, + RCOL_VALS => RCOL_VALS); + end TCOL_DEFS_ADD; + + /* Поиск описания колонки по наименованию */ + function TCOL_DEFS_FIND + ( + RCOL_DEFS in TCOL_DEFS, -- Описание колонок таблицы данных + SNAME in varchar2 -- Наименование + ) return TCOL_DEF -- Найденное описание (null - если не нашли) + is + begin + /* Обходим колонки из коллекции описаний */ + if ((RCOL_DEFS is not null) and (RCOL_DEFS.COUNT > 0)) then + for I in RCOL_DEFS.FIRST .. RCOL_DEFS.LAST + loop + if (RCOL_DEFS(I).SNAME = SNAME) then + return RCOL_DEFS(I); + end if; + end loop; + end if; + /* Ничего не нашли */ + return null; + end TCOL_DEFS_FIND; + + /* Сериализация описания колонки таблицы данных */ + procedure TCOL_DEFS_TO_XML + ( + RCOL_DEFS in TCOL_DEFS -- Описание колонок таблицы данных + ) + is + begin + /* Обходим колонки из коллекции */ + if ((RCOL_DEFS is not null) and (RCOL_DEFS.COUNT > 0)) then + for I in RCOL_DEFS.FIRST .. RCOL_DEFS.LAST + loop + /* Открываем описание колонки */ + PKG_XFAST.DOWN_NODE(SNAME => SRESP_TAG_XCOLUMNS_DEF); + /* Атрибуты колонки */ + PKG_XFAST.ATTR(SNAME => SRESP_ATTR_NAME, SVALUE => RCOL_DEFS(I).SNAME); + PKG_XFAST.ATTR(SNAME => SRESP_ATTR_CAPTION, SVALUE => RCOL_DEFS(I).SCAPTION); + PKG_XFAST.ATTR(SNAME => SRESP_ATTR_DATA_TYPE, SVALUE => RCOL_DEFS(I).SDATA_TYPE); + PKG_XFAST.ATTR(SNAME => SRESP_ATTR_VISIBLE, BVALUE => RCOL_DEFS(I).BVISIBLE); + PKG_XFAST.ATTR(SNAME => SRESP_ATTR_ORDER, BVALUE => RCOL_DEFS(I).BORDER); + PKG_XFAST.ATTR(SNAME => SRESP_ATTR_FILTER, BVALUE => RCOL_DEFS(I).BFILTER); + /* Предопределённые значения */ + if (RCOL_DEFS(I).RCOL_VALS is not null) and (RCOL_DEFS(I).RCOL_VALS.COUNT > 0) then + for V in RCOL_DEFS(I).RCOL_VALS.FIRST .. RCOL_DEFS(I).RCOL_VALS.LAST + loop + /* Открываем описание предопределённого значения */ + PKG_XFAST.DOWN_NODE(SNAME => SRESP_ATTR_VALUES); + /* Значение */ + case RCOL_DEFS(I).SDATA_TYPE + when SDATA_TYPE_STR then + PKG_XFAST.VALUE(SVALUE => RCOL_DEFS(I).RCOL_VALS(V).SVALUE); + when SDATA_TYPE_NUMB then + PKG_XFAST.VALUE(NVALUE => RCOL_DEFS(I).RCOL_VALS(V).NVALUE); + when SDATA_TYPE_DATE then + PKG_XFAST.VALUE(DVALUE => RCOL_DEFS(I).RCOL_VALS(V).DVALUE); + else + P_EXCEPTION(0, + 'Описание колонки "%s" таблицы данных содержит неподдерживаемый тип данных ("%s").', + COALESCE(RCOL_DEFS(I).SNAME, '<НЕ ОПРЕДЕЛЕНА>'), + COALESCE(RCOL_DEFS(I).SDATA_TYPE, '<НЕ ОПРЕДЕЛЁН>')); + end case; + /* Закрываем описание предопределённого значения */ + PKG_XFAST.UP(); + end loop; + end if; + /* Закрываем описание колонки */ + PKG_XFAST.UP(); + end loop; + end if; + end TCOL_DEFS_TO_XML; + + /* Формирование колонки */ + function TCOL_MAKE + ( + SNAME in varchar2, -- Наименование колонки + SVALUE in varchar2 := null, -- Значение (строка) + NVALUE in number := null, -- Значение (число) + DVALUE in date := null -- Значение (дата) + ) return TCOL -- Результат работы + is + RRES TCOL; -- Буфер для результата + begin + /* Формируем объект */ + RRES.SNAME := SNAME; + RRES.RCOL_VAL := TCOL_VAL_MAKE(SVALUE => SVALUE, NVALUE => NVALUE, DVALUE => DVALUE); + /* Возвращаем результат */ + return RRES; + end TCOL_MAKE; + + /* Добавление колонки в коллекцию */ + procedure TCOLS_ADD + ( + RCOLS in out nocopy TCOLS, -- Коллекция колонок + SNAME in varchar2, -- Наименование колонки + SVALUE in varchar2 := null, -- Значение (строка) + NVALUE in number := null, -- Значение (число) + DVALUE in date := null, -- Значение (дата) + BCLEAR in boolean := false -- Флаг очистки коллекции (false - не очищать, true - очистить коллекцию перед добавлением) + ) + is + begin + /* Инициализируем коллекцию если необходимо */ + if ((RCOLS is null) or (BCLEAR)) then + RCOLS := TCOLS(); + end if; + /* Добавляем элемент */ + RCOLS.EXTEND(); + RCOLS(RCOLS.LAST) := TCOL_MAKE(SNAME => SNAME, SVALUE => SVALUE, NVALUE => NVALUE, DVALUE => DVALUE); + end TCOLS_ADD; + + /* Формирование строки */ + function TROW_MAKE + return TROW -- Результат работы + is + RRES TROW; -- Буфер для результата + begin + /* Формируем объект */ + RRES.RCOLS := TCOLS(); + /* Возвращаем результат */ + return RRES; + end TROW_MAKE; + + /* Добавление колонки к строке */ + procedure TROW_ADD_COL + ( + RROW in out nocopy TROW, -- Строка + SNAME in varchar2, -- Наименование колонки + SVALUE in varchar2 := null, -- Значение (строка) + NVALUE in number := null, -- Значение (число) + DVALUE in date := null, -- Значение (дата) + BCLEAR in boolean := false -- Флаг очистки коллекции (false - не очищать, true - очистить коллекцию перед добавлением) + ) + is + begin + /* Сформируем колонку и добавим её к коллекции колонок строки */ + TCOLS_ADD(RCOLS => RROW.RCOLS, SNAME => SNAME, SVALUE => SVALUE, NVALUE => NVALUE, DVALUE => DVALUE, BCLEAR => BCLEAR); + end TROW_ADD_COL; + + /* Добавление строковой колонки к строке из курсора динамического запроса */ + procedure TROW_ADD_CUR_COLS + ( + RROW in out nocopy TROW, -- Строка + SNAME in varchar2, -- Наименование колонки + ICURSOR in integer, -- Курсор + NPOSITION in number, -- Номер колонки в курсоре + BCLEAR in boolean := false -- Флаг очистки коллекции (false - не очищать, true - очистить коллекцию перед добавлением) + ) + is + SVALUE PKG_STD.TLSTRING; -- Буфер для значения курсора + begin + /* Читаем данные из курсора */ + PKG_SQL_DML.COLUMN_VALUE_STR(ICURSOR => ICURSOR, IPOSITION => NPOSITION, SVALUE => SVALUE); + /* Сформируем колонку и добавим её к коллекции колонок строки */ + TCOLS_ADD(RCOLS => RROW.RCOLS, SNAME => SNAME, SVALUE => SVALUE, NVALUE => null, DVALUE => null, BCLEAR => BCLEAR); + end TROW_ADD_CUR_COLS; + + /* Добавление числовой колонки к строке из курсора динамического запроса */ + procedure TROW_ADD_CUR_COLN + ( + RROW in out nocopy TROW, -- Строка + SNAME in varchar2, -- Наименование колонки + ICURSOR in integer, -- Курсор + NPOSITION in number, -- Номер колонки в курсоре + BCLEAR in boolean := false -- Флаг очистки коллекции (false - не очищать, true - очистить коллекцию перед добавлением) + ) + is + NVALUE PKG_STD.TNUMBER; -- Буфер для значения курсора + begin + /* Читаем данные из курсора */ + PKG_SQL_DML.COLUMN_VALUE_NUM(ICURSOR => ICURSOR, IPOSITION => NPOSITION, NVALUE => NVALUE); + /* Сформируем колонку и добавим её к коллекции колонок строки */ + TCOLS_ADD(RCOLS => RROW.RCOLS, SNAME => SNAME, SVALUE => null, NVALUE => NVALUE, DVALUE => null, BCLEAR => BCLEAR); + end TROW_ADD_CUR_COLN; + + /* Добавление колонки типа "дата" к строке из курсора динамического запроса */ + procedure TROW_ADD_CUR_COLD + ( + RROW in out nocopy TROW, -- Строка + SNAME in varchar2, -- Наименование колонки + ICURSOR in integer, -- Курсор + NPOSITION in number, -- Номер колонки в курсоре + BCLEAR in boolean := false -- Флаг очистки коллекции (false - не очищать, true - очистить коллекцию перед добавлением) + ) + is + DVALUE PKG_STD.TLDATE; -- Буфер для значения курсора + begin + /* Читаем данные из курсора */ + PKG_SQL_DML.COLUMN_VALUE_DATE(ICURSOR => ICURSOR, IPOSITION => NPOSITION, DVALUE => DVALUE); + /* Сформируем колонку и добавим её к коллекции колонок строки */ + TCOLS_ADD(RCOLS => RROW.RCOLS, SNAME => SNAME, SVALUE => null, NVALUE => null, DVALUE => DVALUE, BCLEAR => BCLEAR); + end TROW_ADD_CUR_COLD; + + /* Сериализация строки данных таблицы данных */ + procedure TROWS_TO_XML + ( + RCOL_DEFS in TCOL_DEFS, -- Описание колонок таблицы данных + RROWS in TROWS -- Строки таблицы данных + ) + is + RCOL_DEF TCOL_DEF; -- Описание текущей сериализуемой колонки + begin + /* Обходим строки из коллекции */ + if ((RROWS is not null) and (RROWS.COUNT > 0)) then + for I in RROWS.FIRST .. RROWS.LAST + loop + /* Открываем строку */ + PKG_XFAST.DOWN_NODE(SNAME => SRESP_TAG_XROWS); + /* Обходим колонки строки */ + if ((RROWS(I).RCOLS is not null) and (RROWS(I).RCOLS.COUNT > 0)) then + for J in RROWS(I).RCOLS.FIRST .. RROWS(I).RCOLS.LAST + loop + /* Найдём описание колонки */ + RCOL_DEF := TCOL_DEFS_FIND(RCOL_DEFS => RCOL_DEFS, SNAME => RROWS(I).RCOLS(J).SNAME); + if (RCOL_DEF.SNAME is null) then + P_EXCEPTION(0, + 'Описание колонки "%s" таблицы данных не определено.', + RROWS(I).RCOLS(J).SNAME); + end if; + /* Добавлением значение колонки как атрибут строки */ + case RCOL_DEF.SDATA_TYPE + when SDATA_TYPE_STR then + PKG_XFAST.ATTR(SNAME => RROWS(I).RCOLS(J).SNAME, SVALUE => RROWS(I).RCOLS(J).RCOL_VAL.SVALUE); + when SDATA_TYPE_NUMB then + PKG_XFAST.ATTR(SNAME => RROWS(I).RCOLS(J).SNAME, NVALUE => RROWS(I).RCOLS(J).RCOL_VAL.NVALUE); + when SDATA_TYPE_DATE then + PKG_XFAST.ATTR(SNAME => RROWS(I).RCOLS(J).SNAME, DVALUE => RROWS(I).RCOLS(J).RCOL_VAL.DVALUE); + else + P_EXCEPTION(0, + 'Описание колонки "%s" таблицы данных содержит неподдерживаемый тип данных ("%s").', + RCOL_DEFS(I).SNAME, + COALESCE(RCOL_DEFS(I).SDATA_TYPE, '<НЕ ОПРЕДЕЛЁН>')); + end case; + end loop; + end if; + /* Закрываем строку */ + PKG_XFAST.UP(); + end loop; + end if; + end TROWS_TO_XML; + + /* Формирование таблицы данныз */ + function TDATA_GRID_MAKE + return TDATA_GRID -- Результат работы + is + RRES TDATA_GRID; -- Буфер для результата + begin + /* Формируем объект */ + RRES.RCOL_DEFS := TCOL_DEFS(); + RRES.RROWS := TROWS(); + /* Возвращаем результат */ + return RRES; + end TDATA_GRID_MAKE; + + /* Поиск описания колонки в таблице данных по наименованию */ + function TDATA_GRID_FIND_COL_DEF + ( + RDATA_GRID in TDATA_GRID, -- Описание таблицы данных + SNAME in varchar2 -- Наименование колонки + ) return TCOL_DEF -- Найденное описание (null - если не нашли) + is + begin + return TCOL_DEFS_FIND(RCOL_DEFS => RDATA_GRID.RCOL_DEFS, SNAME => SNAME); + end TDATA_GRID_FIND_COL_DEF; + + /* Добавление описания колонки к таблице данных */ + procedure TDATA_GRID_ADD_COL_DEF + ( + RDATA_GRID in out nocopy TDATA_GRID, -- Описание таблицы данных + SNAME in varchar2, -- Наименование колонки + SCAPTION in varchar2, -- Заголовок колонки + SDATA_TYPE in varchar2 := SDATA_TYPE_STR, -- Тип данных колонки (см. константы SDATA_TYPE_*) + SCOND_FROM in varchar2 := null, -- Наименование нижней границы условия отбора (null - используется UTL_COND_NAME_MAKE_FROM) + SCOND_TO in varchar2 := null, -- Наименование верхней границы условия отбора (null - используется UTL_COND_NAME_MAKE_TO) + BVISIBLE in boolean := true, -- Разрешить отображение + BORDER in boolean := false, -- Разрешить сортировку по колонке + BFILTER in boolean := false, -- Разрешить отбор по колонке + RCOL_VALS in TCOL_VALS := null, -- Предопределённые значения колонки + BCLEAR in boolean := false -- Флаг очистки коллекции описаний колонок таблицы данных (false - не очищать, true - очистить коллекцию перед добавлением) + ) + is + begin + /* Формируем описание и добавляем в коллекцию таблицы данных */ + TCOL_DEFS_ADD(RCOL_DEFS => RDATA_GRID.RCOL_DEFS, + SNAME => SNAME, + SCAPTION => SCAPTION, + SDATA_TYPE => SDATA_TYPE, + SCOND_FROM => SCOND_FROM, + SCOND_TO => SCOND_TO, + BVISIBLE => BVISIBLE, + BORDER => BORDER, + BFILTER => BFILTER, + RCOL_VALS => RCOL_VALS, + BCLEAR => BCLEAR); + end TDATA_GRID_ADD_COL_DEF; + + /* Добавление описания колонки к таблице данных */ + procedure TDATA_GRID_ADD_ROW + ( + RDATA_GRID in out nocopy TDATA_GRID, -- Описание таблицы данных + RROW in TROW, -- Строка + BCLEAR in boolean := false -- Флаг очистки коллекции строк таблицы данных (false - не очищать, true - очистить коллекцию перед добавлением) + ) + is + begin + /* Инициализируем коллекцию если необходимо */ + if ((RDATA_GRID.RROWS is null) or (BCLEAR)) then + RDATA_GRID.RROWS := TROWS(); + end if; + /* Добавляем элемент */ + RDATA_GRID.RROWS.EXTEND(); + RDATA_GRID.RROWS(RDATA_GRID.RROWS.LAST) := RROW; + end TDATA_GRID_ADD_ROW; + + /* Сериализация таблицы данных */ + function TDATA_GRID_TO_XML + ( + RDATA_GRID in TDATA_GRID, -- Описание таблицы данных + NINCLUDE_DEF in number := 1 -- Включить описание колонок (0 - нет, 1 - да) + ) return clob -- XML-описание + is + CRES clob; -- Буфер для результата + begin + /* Начинаем формирование XML */ + PKG_XFAST.PROLOGUE(ITYPE => PKG_XFAST.CONTENT_); + /* Открываем корень */ + PKG_XFAST.DOWN_NODE(SNAME => SRESP_TAG_XDATA); + /* Если необходимо включить описание колонок */ + if (NINCLUDE_DEF = 1) then + TCOL_DEFS_TO_XML(RCOL_DEFS => RDATA_GRID.RCOL_DEFS); + end if; + /* Формируем описание строк */ + TROWS_TO_XML(RCOL_DEFS => RDATA_GRID.RCOL_DEFS,RROWS => RDATA_GRID.RROWS); + /* Закрываем корень */ + PKG_XFAST.UP(); + /* Сериализуем */ + CRES := PKG_XFAST.SERIALIZE_TO_CLOB(); + /* Завершаем формирование XML */ + PKG_XFAST.EPILOGUE(); + /* Возвращаем полученное */ + return CRES; + exception + when others then + /* Завершаем формирование XML */ + PKG_XFAST.EPILOGUE(); + /* Вернем ошибку */ + PKG_STATE.DIAGNOSTICS_STACKED(); + P_EXCEPTION(0, PKG_STATE.SQL_ERRM()); + end TDATA_GRID_TO_XML; + + /* Конвертация значений фильтра в число */ + procedure TFILTER_TO_NUMBER + ( + RFILTER in TFILTER, -- Фильтр + NFROM out number, -- Значение нижней границы диапазона + NTO out number -- Значение верхней границы диапазона + ) + is + begin + /* Нижняя граница диапазона */ + if (RFILTER.SFROM is not null) then + begin + NFROM := PKG_P8PANELS_BASE.UTL_S2N(SVALUE => RFILTER.SFROM); + exception + when others then + P_EXCEPTION(0, + 'Неверный формат числа (%s) в указанной нижней границе диапазона фильтра.', + RFILTER.SFROM); + end; + end if; + /* Верхняя граница диапазона */ + if (RFILTER.STO is not null) then + begin + NTO := PKG_P8PANELS_BASE.UTL_S2N(SVALUE => RFILTER.STO); + exception + when others then + P_EXCEPTION(0, + 'Неверный формат числа (%s) в указанной верхней границе диапазона фильтра.', + RFILTER.STO); + end; + end if; + end TFILTER_TO_NUMBER; + + /* Конвертация значений фильтра в дату */ + procedure TFILTER_TO_DATE + ( + RFILTER in TFILTER, -- Фильтр + DFROM out date, -- Значение нижней границы диапазона + DTO out date -- Значение верхней границы диапазона + ) + is + begin + /* Нижняя граница диапазона */ + if (RFILTER.SFROM is not null) then + begin + DFROM := PKG_P8PANELS_BASE.UTL_S2D(SVALUE => RFILTER.SFROM); + exception + when others then + P_EXCEPTION(0, + 'Неверный формат даты (%s) в указанной нижней границе диапазона фильтра.', + RFILTER.SFROM); + end; + end if; + /* Верхняя граница диапазона */ + if (RFILTER.STO is not null) then + begin + DTO := PKG_P8PANELS_BASE.UTL_S2D(SVALUE => RFILTER.STO); + exception + when others then + P_EXCEPTION(0, + 'Неверный формат даты (%s) в указанной верхней границе диапазона фильтра.', + RFILTER.STO); + end; + end if; + end TFILTER_TO_DATE; + + /* Формирование фильтра */ + function TFILTER_MAKE + ( + SNAME in varchar2, -- Наименование + SFROM in varchar2, -- Значение "с" + STO in varchar2 -- Значение "по" + ) return TFILTER -- Результат работы + is + RRES TFILTER; -- Буфер для результата + begin + /* Формируем объект */ + RRES.SNAME := SNAME; + RRES.SFROM := SFROM; + RRES.STO := STO; + /* Возвращаем результат */ + return RRES; + end TFILTER_MAKE; + + /* Поиск фильтра в коллекции */ + function TFILTERS_FIND + ( + RFILTERS in TFILTERS, -- Коллекция фильтров + SNAME in varchar2 -- Наименование + ) return TFILTER -- Найденный фильтр (null - если не нашли) + is + begin + /* Обходим фильтры из коллекции */ + if ((RFILTERS is not null) and (RFILTERS.COUNT > 0)) then + for I in RFILTERS.FIRST .. RFILTERS.LAST + loop + if (RFILTERS(I).SNAME = SNAME) then + return RFILTERS(I); + end if; + end loop; + end if; + /* Ничего не нашли */ + return null; + end TFILTERS_FIND; + + /* Десериализация фильтров */ + function TFILTERS_FROM_XML + ( + CFILTERS in clob -- Сериализованное представление фильтров (BASE64(ИМЯЗНАЧЕНИЕЗНАЧЕНИЕ...)) + ) return TFILTERS -- Результат работы + is + RFILTERS TFILTERS; -- Буфер для результата работы + XDOC PKG_XPATH.TDOCUMENT; -- Документ XML + XROOT PKG_XPATH.TNODE; -- Корень документа XML + XNODE PKG_XPATH.TNODE; -- Буфер узла документа + XNODES PKG_XPATH.TNODES; -- Буфер коллекции узлов документа + begin + /* Вернём выходную коллекцию */ + RFILTERS := TFILTERS(); + /* Разбираем XML */ + XDOC := PKG_XPATH.PARSE_FROM_CLOB(LCXML => '<' || SRQ_TAG_XROOT || '>' || + BLOB2CLOB(LBDATA => BASE64_DECODE(LCSRCE => CFILTERS), + SCHARSET => PKG_CHARSET.CHARSET_UTF_()) || ''); + /* Считываем корневой узел */ + XROOT := PKG_XPATH.ROOT_NODE(RDOCUMENT => XDOC); + /* Считывание списка записей */ + XNODES := PKG_XPATH.LIST_NODES(RPARENT_NODE => XROOT, SPATTERN => '/' || SRQ_TAG_XROOT || '/' || SRQ_TAG_XFILTERS); + /* Цикл по списку записией */ + for I in 1 .. PKG_XPATH.COUNT_NODES(RNODES => XNODES) + loop + /* Считаем элемент по его номеру */ + XNODE := PKG_XPATH.ITEM_NODE(RNODES => XNODES, INUMBER => I); + /* Добавим его в коллекцию */ + RFILTERS.EXTEND(); + RFILTERS(RFILTERS.LAST) := TFILTER_MAKE(SNAME => PKG_XPATH.VALUE(RNODE => XNODE, SPATTERN => SRQ_TAG_SNAME), + SFROM => PKG_XPATH.VALUE(RNODE => XNODE, SPATTERN => SRQ_TAG_SFROM), + STO => PKG_XPATH.VALUE(RNODE => XNODE, SPATTERN => SRQ_TAG_STO)); + end loop; + /* Освободим документ */ + PKG_XPATH.FREE(RDOCUMENT => XDOC); + /* Вернём результат */ + return RFILTERS; + exception + when others then + /* Освободим документ */ + PKG_XPATH.FREE(RDOCUMENT => XDOC); + /* Вернем ошибку */ + PKG_STATE.DIAGNOSTICS_STACKED(); + P_EXCEPTION(0, PKG_STATE.SQL_ERRM()); + end TFILTERS_FROM_XML; + + /* Применение параметров фильтрации в запросе */ + procedure TFILTERS_SET_QUERY + ( + NIDENT in number, -- Идентификатор отбора + NCOMPANY in number, -- Рег. номер организации + NPARENT in number := null, -- Рег. номер родителя + SUNIT in varchar2, -- Код раздела + SPROCEDURE in varchar2, -- Наименование серверной процедуры отбора + RDATA_GRID in TDATA_GRID, -- Описание таблицы данных + RFILTERS in TFILTERS -- Коллекция фильтров + ) + is + RCOL_DEF TCOL_DEF; -- Описание текущей фильтруемой колонки + BENUM boolean; -- Флаг начиличия перечисляемых значений + NFROM PKG_STD.TNUMBER; -- Буфер для верхней границы диапазона отбора чисел + NTO PKG_STD.TNUMBER; -- Буфер для нижней границы диапазона отбора чисел + DFROM PKG_STD.TLDATE; -- Буфер для верхней границы диапазона отбора дат + DTO PKG_STD.TLDATE; -- Буфер для нижней границы диапазона отбора дат + begin + /* Формирование условий отбора - Пролог */ + PKG_COND_BROKER.PROLOGUE(IMODE => PKG_COND_BROKER.MODE_SMART_, NIDENT => NIDENT); + /* Формирование условий отбора - Установка процедуры серверного отбора */ + PKG_COND_BROKER.SET_PROCEDURE(SPROCEDURE_NAME => SPROCEDURE); + /* Формирование условий отбора - Установка раздела */ + PKG_COND_BROKER.SET_UNIT(SUNITCODE => SUNIT); + /* Формирование условий отбора - Установка организации */ + PKG_COND_BROKER.SET_COMPANY(NCOMPANY => NCOMPANY); + /* Формирование условий отбора - Установка родителя */ + if (NPARENT is not null) then + PKG_COND_BROKER.SET_PARENT(NPARENT => NPARENT); + end if; + /* Обходим фильтр, если задан */ + if ((RFILTERS is not null) and (RFILTERS.COUNT > 0)) then + for I in RFILTERS.FIRST .. RFILTERS.LAST + loop + /* Найдем фильтруемую колонку в описании */ + RCOL_DEF := TCOL_DEFS_FIND(RCOL_DEFS => RDATA_GRID.RCOL_DEFS, SNAME => RFILTERS(I).SNAME); + if (RCOL_DEF.SNAME is not null) then + /* Определимся с наличием перечисляемых значений */ + if ((RCOL_DEF.RCOL_VALS is not null) and (RCOL_DEF.RCOL_VALS.COUNT > 0)) then + BENUM := true; + else + BENUM := false; + end if; + /* Установим для неё условие отобра согласно типу данных */ + case RCOL_DEF.SDATA_TYPE + when SDATA_TYPE_STR then + begin + if (BENUM) then + PKG_COND_BROKER.SET_CONDITION_ESTR(SCONDITION_NAME => RCOL_DEF.SCOND_FROM, + SCONDITION_ESTR => RFILTERS(I).SFROM, + ICASE_INSENSITIVE => 1); + else + PKG_COND_BROKER.SET_CONDITION_STR(SCONDITION_NAME => RCOL_DEF.SCOND_FROM, + SCONDITION_VALUE => RFILTERS(I).SFROM, + ICASE_INSENSITIVE => 1); + end if; + end; + when SDATA_TYPE_NUMB then + begin + if (BENUM) then + PKG_COND_BROKER.SET_CONDITION_ENUM(SCONDITION_NAME => RCOL_DEF.SCOND_FROM, + SCONDITION_ENUM => RFILTERS(I).SFROM); + else + TFILTER_TO_NUMBER(RFILTER => RFILTERS(I), NFROM => NFROM, NTO => NTO); + if (NFROM is not null) then + PKG_COND_BROKER.SET_CONDITION_NUM(SCONDITION_NAME => RCOL_DEF.SCOND_FROM, + NCONDITION_VALUE => NFROM); + end if; + if (NTO is not null) then + PKG_COND_BROKER.SET_CONDITION_NUM(SCONDITION_NAME => RCOL_DEF.SCOND_TO, NCONDITION_VALUE => NTO); + end if; + end if; + end; + when SDATA_TYPE_DATE then + begin + if (BENUM) then + PKG_COND_BROKER.SET_CONDITION_EDATE(SCONDITION_NAME => RCOL_DEF.SCOND_FROM, + SCONDITION_EDATE => RFILTERS(I).SFROM); + else + TFILTER_TO_DATE(RFILTER => RFILTERS(I), DFROM => DFROM, DTO => DTO); + if (DFROM is not null) then + PKG_COND_BROKER.SET_CONDITION_DATE(SCONDITION_NAME => RCOL_DEF.SCOND_FROM, + DCONDITION_VALUE => DFROM); + end if; + if (DTO is not null) then + PKG_COND_BROKER.SET_CONDITION_DATE(SCONDITION_NAME => RCOL_DEF.SCOND_TO, DCONDITION_VALUE => DTO); + end if; + end if; + end; + else + P_EXCEPTION(0, + 'Описание колонки "%s" таблицы данных содержит неподдерживаемый тип данных ("%s").', + RCOL_DEF.SNAME, + COALESCE(RCOL_DEF.SDATA_TYPE, '<НЕ ОПРЕДЕЛЁН>')); + end case; + end if; + end loop; + end if; + /* Формирование условий отбора - Эпилог */ + PKG_COND_BROKER.EPILOGUE(); + end TFILTERS_SET_QUERY; + + /* Формирование сортировки */ + function TORDER_MAKE + ( + SNAME in varchar2, -- Наименование + SDIRECTION in varchar2 -- Направление (см. константы SORDER_DIRECTION_*) + ) return TORDER -- Результат работы + is + RRES TORDER; -- Буфер для результата + begin + /* Формируем объект */ + RRES.SNAME := SNAME; + RRES.SDIRECTION := SDIRECTION; + /* Возвращаем результат */ + return RRES; + end TORDER_MAKE; + + /* Десериализация сортировок */ + function TORDERS_FROM_XML + ( + CORDERS in clob -- Сериализованное представление сотрировок (BASE64(ИМЯASC/DESC...)) + ) return TORDERS -- Результат работы + is + RORDERS TORDERS; -- Буфер для результата работы + XDOC PKG_XPATH.TDOCUMENT; -- Документ XML + XROOT PKG_XPATH.TNODE; -- Корень документа XML + XNODE PKG_XPATH.TNODE; -- Буфер узла документа + XNODES PKG_XPATH.TNODES; -- Буфер коллекции узлов документа + begin + /* Инициализируем выходную коллекцию */ + RORDERS := TORDERS(); + /* Разбираем XML */ + XDOC := PKG_XPATH.PARSE_FROM_CLOB(LCXML => '<' || SRQ_TAG_XROOT || '>' || + BLOB2CLOB(LBDATA => BASE64_DECODE(LCSRCE => CORDERS), + SCHARSET => PKG_CHARSET.CHARSET_UTF_()) || ''); + /* Считываем корневой узел */ + XROOT := PKG_XPATH.ROOT_NODE(RDOCUMENT => XDOC); + /* Считывание списка записей */ + XNODES := PKG_XPATH.LIST_NODES(RPARENT_NODE => XROOT, SPATTERN => '/' || SRQ_TAG_XROOT || '/' || SRQ_TAG_XORDERS); + /* Цикл по списку записией */ + for I in 1 .. PKG_XPATH.COUNT_NODES(RNODES => XNODES) + loop + /* Считаем элемент по его номеру */ + XNODE := PKG_XPATH.ITEM_NODE(RNODES => XNODES, INUMBER => I); + /* Добавим его в коллекцию */ + RORDERS.EXTEND(); + RORDERS(RORDERS.LAST) := TORDER_MAKE(SNAME => PKG_XPATH.VALUE(RNODE => XNODE, SPATTERN => SRQ_TAG_SNAME), + SDIRECTION => PKG_XPATH.VALUE(RNODE => XNODE, SPATTERN => SRQ_TAG_SDIRECTION)); + end loop; + /* Освободим документ */ + PKG_XPATH.FREE(RDOCUMENT => XDOC); + /* Вернём результат */ + return RORDERS; + exception + when others then + /* Освободим документ */ + PKG_XPATH.FREE(RDOCUMENT => XDOC); + /* Вернем ошибку */ + PKG_STATE.DIAGNOSTICS_STACKED(); + P_EXCEPTION(0, PKG_STATE.SQL_ERRM()); + end TORDERS_FROM_XML; + + /* Применение параметров сортировки в запросе */ + procedure TORDERS_SET_QUERY + ( + RDATA_GRID in TDATA_GRID, -- Описание таблицы + RORDERS in TORDERS, -- Коллекция сортировок + SPATTERN in varchar2, -- Шаблон для подстановки условий отбора в запрос + CSQL in out nocopy clob -- Буфер запроса + ) + is + CSQL_ORDERS clob; -- Буфер для условий сортировки в запросе + begin + /* Если сортировка задана */ + if ((RORDERS is not null) and (RORDERS.COUNT > 0)) then + CSQL_ORDERS := ' order by '; + for I in RORDERS.FIRST .. RORDERS.LAST + loop + /* Перед добавлением в запрос - обязательная проверка, чтобы избежать SQL-инъекций */ + if ((TCOL_DEFS_FIND(RCOL_DEFS => RDATA_GRID.RCOL_DEFS, SNAME => RORDERS(I).SNAME).SNAME is not null) and + (RORDERS(I).SDIRECTION in (SORDER_DIRECTION_ASC, SORDER_DIRECTION_DESC))) then + CSQL_ORDERS := CSQL_ORDERS || RORDERS(I).SNAME || ' ' || RORDERS(I).SDIRECTION; + if (I < RORDERS.LAST) then + CSQL_ORDERS := CSQL_ORDERS || ', '; + end if; + end if; + end loop; + end if; + CSQL := replace(CSQL, SPATTERN, CSQL_ORDERS); + end TORDERS_SET_QUERY; + +end PKG_P8PANELS_VISUAL; +/ diff --git a/db/UDO_P_P8PANELS_AGNLIST.prc b/db/UDO_P_P8PANELS_AGNLIST.prc new file mode 100644 index 0000000..a4cc187 --- /dev/null +++ b/db/UDO_P_P8PANELS_AGNLIST.prc @@ -0,0 +1,143 @@ +create or replace procedure UDO_P_P8PANELS_AGNLIST +( + 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.TFILTERS; -- Фильтры + RO PKG_P8PANELS_VISUAL.TORDERS; -- Сортировки + RDG PKG_P8PANELS_VISUAL.TDATA_GRID; -- Описание таблицы + RDG_ROW PKG_P8PANELS_VISUAL.TROW; -- Строка таблицы + RCOL_VALS PKG_P8PANELS_VISUAL.TCOL_VALS; -- Предопределённые значения столбцов + NROW_FROM PKG_STD.TREF; -- Номер строки с + NROW_TO PKG_STD.TREF; -- Номер строки по + CSQL clob; -- Буфер для запроса + ICURSOR integer; -- Курсор для исполнения запроса + RAGENT AGNLIST%rowtype; -- Буфер для записи курсора +begin + /* Читаем фильтры */ + RF := PKG_P8PANELS_VISUAL.TFILTERS_FROM_XML(CFILTERS => CFILTERS); + /* Читем сортировки */ + RO := PKG_P8PANELS_VISUAL.TORDERS_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.TDATA_GRID_MAKE(); + /* Добавляем в таблицу описание колонок */ + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'RN', + SCAPTION => 'Рег. номер', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, + BVISIBLE => false); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'AGNABBR', + SCAPTION => 'Мнемокод', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + SCOND_FROM => 'AgentAbbr', + BORDER => true, + BFILTER => true); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'AGNNAME', + SCAPTION => 'Наименование', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + SCOND_FROM => 'AgentName', + BORDER => true, + BFILTER => true); + PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 0, BCLEAR => true); + PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 1); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'AGNTYPE', + SCAPTION => 'Тип', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, + SCOND_FROM => 'AgentType', + BORDER => true, + BFILTER => true, + RCOL_VALS => RCOL_VALS); + PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'AGNBURN', + SCAPTION => 'Дата рождения', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_DATE, + SCOND_FROM => 'AgentBornFrom', + SCOND_TO => 'AgentBornTo', + BORDER => true, + BFILTER => true); + /* Обходим данные */ + begin + /* Собираем запрос */ + CSQL := 'select * + from (select D.*, + ROWNUM NROW + from (select AG.RN, + AG.AGNABBR, + AG.AGNNAME, + AG.AGNTYPE, + AG.AGNBURN + from AGNLIST AG + where AG.RN in (select ID from COND_BROKER_IDSMART where IDENT = :NIDENT) %ORDER_BY%) D) F + where F.NROW between :NROW_FROM and :NROW_TO'; + /* Учтём сортировки */ + PKG_P8PANELS_VISUAL.TORDERS_SET_QUERY(RDATA_GRID => RDG, RORDERS => RO, SPATTERN => '%ORDER_BY%', CSQL => CSQL); + /* Учтём фильтры */ + PKG_P8PANELS_VISUAL.TFILTERS_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_NUM(ICURSOR => ICURSOR, IPOSITION => 1); + PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 2); + PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 3); + PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 4); + PKG_SQL_DML.DEFINE_COLUMN_DATE(ICURSOR => ICURSOR, IPOSITION => 5); + /* Делаем выборку */ + 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_NUM(ICURSOR => ICURSOR, IPOSITION => 1, NVALUE => RAGENT.RN); + PKG_SQL_DML.COLUMN_VALUE_STR(ICURSOR => ICURSOR, IPOSITION => 2, SVALUE => RAGENT.AGNABBR); + PKG_SQL_DML.COLUMN_VALUE_STR(ICURSOR => ICURSOR, IPOSITION => 3, SVALUE => RAGENT.AGNNAME); + PKG_SQL_DML.COLUMN_VALUE_NUM(ICURSOR => ICURSOR, IPOSITION => 4, NVALUE => RAGENT.AGNTYPE); + PKG_SQL_DML.COLUMN_VALUE_DATE(ICURSOR => ICURSOR, IPOSITION => 5, DVALUE => RAGENT.AGNBURN); + /* Инициализируем строку таблицы данных */ + RDG_ROW := PKG_P8PANELS_VISUAL.TROW_MAKE(); + /* Добавляем колонки с данными */ + PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'RN', NVALUE => RAGENT.RN); + PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'AGNABBR', SVALUE => RAGENT.AGNABBR); + PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'AGNNAME', SVALUE => RAGENT.AGNNAME); + PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'AGNTYPE', NVALUE => RAGENT.AGNTYPE); + PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'AGNBURN', DVALUE => RAGENT.AGNBURN); + /* Добавляем строку в таблицу */ + PKG_P8PANELS_VISUAL.TDATA_GRID_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.TDATA_GRID_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => NINCLUDE_DEF); +end; +/ diff --git a/db/UDO_P_P8PANELS_TEST.prc b/db/UDO_P_P8PANELS_TEST.prc new file mode 100644 index 0000000..d93271d --- /dev/null +++ b/db/UDO_P_P8PANELS_TEST.prc @@ -0,0 +1,23 @@ +create or replace procedure UDO_P_P8PANELS_TEST +( + NRN in number, + DDATE in date, + CFILTERS in clob, + CORDERS in clob, + NRES out number, + SRES out varchar2, + COUT out clob, + DD out date +) +is +begin + NRES:=NRN*2; + --DBMS_LOCK.SLEEP(3); + if (DDATE is not null) then p_exception(0, to_char(ddate, 'dd.mm.yyyy hh24:mi:ss')); end if; + SRES:='Очень хорошая погода'; + COUT:='Просто текст'; + --COUT:='333444123dfgsfg'; + --COUT:='333444qqq555qsvfvr432123dfgsfg'; + DD := DDATE; +end; +/