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_()) || '' ||
+ SRQ_TAG_XROOT || '>');
+ /* Считываем корневой узел */
+ 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_()) || '' ||
+ SRQ_TAG_XROOT || '>');
+ /* Считываем корневой узел */
+ 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;
+/