P8-Panels/db/PKG_P8PANELS_PROJECTS.pck

7710 lines
515 KiB
SQL
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
/* Типы данных - статьи структуры цены этапа проекта (для панели "Информация о проектах") */
type TINFO_STAGE_ART is record
(
NRN CONTRPRCLC.RN%type, -- Рег. номер записи структуры цены
NCOST_STATUS PKG_STD.TNUMBER, -- Состояние затрат статьи (-1 - не определено, 0 - без отклонений, 1 - расходом больше 90%, 2 - перерасход)
NFACEACC FACEACC.RN%type, -- Рег. номер лицевого счёта затрат связанного этапа проекта
NFPDARTCL FPDARTCL.RN%type, -- Рег. номер статьи затрат
SFPDARTCL FPDARTCL.CODE%type, -- Код статьи затрат
NPLAN_SUM PKG_STD.TSUMM, -- Сумма затрат (план)
NFACT_SUM PKG_STD.TSUMM, -- Сумма затрат (факт)
NPLAN_FACT_SUM PKG_STD.TSUMM, -- Отклонение (план - факт)
SCURNAMES CURNAMES.INTCODE%type, -- Код валюты
NCOST_CTL boolean -- Подлежит контролю затрат
);
/* Типы данных - коллекция статей структуры цены этапа проекта (для панели "Информация о проектах") */
type TINFO_STAGE_ARTS is table of TINFO_STAGE_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 - есть отклонения)
/* Получение % готовности проекта (по затратам) */
function GET_COST_READY
(
NRN in number -- Рег. номер проекта
) return number; -- % готовности
/* Список проектов */
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 GRAPH
(
COUT out clob -- График проектов
);
/* График по данным проектов - "Топ проблем" */
procedure CHART_PROBLEMS
(
COUT out clob -- Сериализованный график
);
/* График по данным проектов - "Топ заказчиков" */
procedure CHART_CUSTOMERS
(
COUT out clob -- Сериализованный график
);
/* График по данным проектов - "Затраты на проекты" */
procedure CHART_FCCOSTNOTES
(
COUT out clob -- Сериализованный график
);
/* График по данным проектов - "Затраты на проекты" (подбор записей журнала затрат по точке графика) */
procedure CHART_FCCOSTNOTES_SELECT_COST
(
NYEAR in number, -- Год
NMONTH in number, -- Месяц
NIDENT out number -- Идентификатор буфера подобранных (списка отмеченных записей, null - не найдено)
);
/* Отбор этапов проектов */
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; -- Состояние (null - не определено, 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; -- Состояние (null - не определено, 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; -- Состояние (null - не определено, 0 - без отклонений, 1 - есть отклонения)
/* Получение остатка срока исполнения этапа проекта */
function STAGES_GET_DAYS_LEFT
(
NRN in number -- Рег. номер этапа проекта
) return number; -- Количество дней (null - не определено)
/* Подбор записей журнала затрат этапа проекта */
procedure STAGES_SELECT_COST_FACT
(
NRN in number, -- Рег. номер этапа проекта
NIDENT out number -- Идентификатор буфера подобранных (списка отмеченных записей, null - не найдено)
);
/* Получение суммы фактических затрат этапа проекта */
function STAGES_GET_COST_FACT
(
NRN in number -- Рег. номер этапа проекта
) return number; -- Сумма фактических затрат
/* Подбор записей расходных накладных на отпуск потребителям этапа проекта */
procedure STAGES_SELECT_SUMM_REALIZ
(
NRN in number, -- Рег. номер этапа проекта
NIDENT out number -- Идентификатор буфера подобранных (списка отмеченных записей, null - не найдено)
);
/* Получение суммы реализации этапа проекта */
function STAGES_GET_SUMM_REALIZ
(
NRN in number, -- Рег. номер этапа проекта
NFPDARTCL_REALIZ in number -- Рег. номер статьи калькуляции для реализации
) return number; -- Сумма реализации
/* Получение % готовности этапа проекта (по затратам) */
function STAGES_GET_COST_READY
(
NRN 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 -- Сериализованная таблица данных
);
/* Подбор записей журнала затрат по статье калькуляции этапа проекта */
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, -- Рег. номер этапа проекта
NFPDARTCL in number := null, -- Рег. номер статьи затрат (null - брать все)
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_SELECT_PAY_IN
(
NPROJECTSTAGEPF in number, -- Рег. номер соисполнителя этапа проекта
NIDENT out number -- Идентификатор буфера подобранных (списка отмеченных записей, null - не найдено)
);
/* Подбор приходных накладных соисполнителя этапа проекта */
procedure STAGE_CONTRACTS_SELECT_ININV
(
NPROJECTSTAGEPF in number, -- Рег. номер соисполнителя этапа проекта
NIDENT out number -- Идентификатор буфера подобранных (списка отмеченных записей, null - не найдено)
);
/* Подбор платежей финансирования соисполнителя этапа проекта */
procedure STAGE_CONTRACTS_SELECT_FIN_OUT
(
NPROJECTSTAGEPF in number, -- Рег. номер соисполнителя этапа проекта
NIDENT out number -- Идентификатор буфера подобранных (списка отмеченных записей, null - не найдено)
);
/* Получение состояния финансирования по договору соисполнителя этапа проекта */
function STAGE_CONTRACTS_GET_CTRL_FIN
(
NPROJECTSTAGEPF in number -- Рег. номер соисполнителя этапа проекта
) return number; -- Состояние (null - не определено, 0 - без отклонений, 1 - есть отклонения)
/* Получение состояния соисполнения по договору соисполнителя этапа проекта */
function STAGE_CONTRACTS_GET_CTRL_COEXE
(
NPROJECTSTAGEPF in number -- Рег. номер соисполнителя этапа проекта
) return number; -- Состояние (null - не определено, 0 - без отклонений, 1 - есть отклонения)
/* Получение сведений по договору соисполнителя этапа проекта */
procedure STAGE_CONTRACTS_GET
(
NPROJECTSTAGEPF in number, -- Рег. номер соисполнителя этапа проекта
NINC_FIN in number := 0, -- Включить сведения о финансировании (0 - нет, 1 - да)
NINC_COEXEC in number := 0, -- Включить сведения о соисполнении (0 - нет, 1 - да)
NPAY_IN out number, -- Сведения о финансировании - сумма акцептованных счетов на оплату
NFIN_OUT out number, -- Сведения о финансировании - сумма оплаченных счетов на оплату
NPAY_IN_REST out number, -- Сведения о финансировании - сумма оставшихся к оплате счетов на оплату
NFIN_REST out number, -- Сведения о финансировании - общий остаток к оплате по договору
NCTRL_FIN out number, -- Сведения о финансировании - состояние (null - не определено, 0 - без отклонений, 1 - есть отклонения)
NCOEXEC_IN out number, -- Сведения о соисполнении - получено актов/накладных
NCOEXEC_REST out number, -- Сведения о соисполнении - остаток к актированию/поставке
NCTRL_COEXEC out number -- Сведения о соисполнении - состояние (null - не определено, 0 - без отклонений, 1 - есть отклонения)
);
/* Список договоров этапа проекта */
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 -- Сериализованная таблица данных
);
/* Получение списка проектов */
procedure JB_PRJCTS_LIST
(
NIDENT in number, -- Идентификатор процесса
COUT out clob -- Список проектов
);
/* Изменение сроков работы в буфере балансировки */
procedure JB_JOBS_MODIFY_PERIOD
(
NJB_JOBS in number, -- Рег. номер записи балансируемой работы/этапа
DDATE_FROM in date, -- Новая дата начала
DDATE_TO in date, -- Новая дата окончания
NRESOURCE_STATUS out number -- Состояние ресурсов (0 - без отклонений, 1 - есть отклонения, -1 - ничего не изменяли)
);
/* Получение списка работ проектов для диаграммы Ганта */
procedure JB_JOBS_LIST
(
NIDENT in number, -- Идентификатор процесса
NPRN in number, -- Рег. номер родителя
NINCLUDE_DEF in number, -- Признак включения описания диаграммы в ответ
COUT out clob -- Список проектов
);
/* Получение списка для детализации трудоёмкости по ФОТ периода балансировки */
procedure JB_PERIODS_PLAN_FOT_LIST
(
NJB_PERIODS in number, -- Рег. номер записи периода в буфере балансировки
NPAGE_NUMBER in number, -- Номер страницы (игнорируется при NPAGE_SIZE=0)
NPAGE_SIZE in number, -- Количество записей на странице (0 - все)
CORDERS in clob, -- Сортировки
NINCLUDE_DEF in number, -- Признак включения описания колонок таблицы в ответ
COUT out clob -- Сериализованная таблица данных
);
/* Получение списка для детализации фактической трудоёмкости периода балансировки по "Планам и отчетам подразделений" */
procedure JB_PERIODS_FACT_RPT_LIST
(
NJB_PERIODS in number, -- Рег. номер записи периода в буфере балансировки
NPAGE_NUMBER in number, -- Номер страницы (игнорируется при NPAGE_SIZE=0)
NPAGE_SIZE in number, -- Количество записей на странице (0 - все)
CORDERS in clob, -- Сортировки
NINCLUDE_DEF in number, -- Признак включения описания колонок таблицы в ответ
COUT out clob -- Сериализованная таблица данных
);
/* Получение списка для детализации трудоёмкости периода балансировки по текущему состоянию графика */
procedure JB_PERIODS_PLAN_JOBS_LIST
(
NJB_PERIODS in number, -- Рег. номер записи периода в буфере балансировки
NPAGE_NUMBER in number, -- Номер страницы (игнорируется при NPAGE_SIZE=0)
NPAGE_SIZE in number, -- Количество записей на странице (0 - все)
CORDERS in clob, -- Сортировки
NINCLUDE_DEF in number, -- Признак включения описания колонок таблицы в ответ
COUT out clob -- Сериализованная таблица данных
);
/* Пересчёт периодов балансировки */
procedure JB_PERIODS_RECALC
(
NIDENT in number, -- Идентификатор процесса
NINITIAL in number, -- Признак первоначального рассчёта (0 - пересчёт, 1 - первоначальный рассчёт)
NRESOURCE_STATUS out number -- Состояние ресурсов (0 - без отклонений, 1 - есть отклонения)
);
/* Список периодов балансировки */
procedure JB_PERIODS_LIST
(
NIDENT in number, -- Идентификатор процесса
NPAGE_NUMBER in number, -- Номер страницы (игнорируется при NPAGE_SIZE=0)
NPAGE_SIZE in number, -- Количество записей на странице (0 - все)
CORDERS in clob, -- Сортировки
NINCLUDE_DEF in number, -- Признак включения описания колонок таблицы в ответ
COUT out clob -- Сериализованная таблица данных
);
/* Очистка данных балансировки */
procedure JB_CLEAN
(
NIDENT in number -- Идентификатор процесса
);
/* Перенос данных буфера балансировки в проекты */
procedure JB_SAVE
(
NIDENT in number, -- Идентификатор процесса
COUT out clob -- Список проектов
);
/* Формирование исходных данных для балансировки планов-графиков работ */
procedure JB_INIT
(
DBEGIN in out date, -- Дата начала периода мониторинга загрузки ресурсов
DFACT in out date, -- Факт по состоянию на
NDURATION_MEAS out number, -- Единица измерения длительности (0 - день, 1 - неделя, 2 - декада, 3 - месяц, 4 - квартал, 5 - год)
SDURATION_MEAS out varchar2, -- Единица измерения длительности (мнемокод)
NLAB_MEAS out number, -- Единица измерения трудоёмкости
SLAB_MEAS out varchar2, -- Единица измерения трудоёмкости (мнемокод)
NIDENT in out number, -- Идентификатор процесса (null - сгенерировать новый, !null - удалить старые данные и пересоздать с указанным идентификатором)
NRESOURCE_STATUS out number -- Состояние ресурсов (0 - без отклонений, 1 - есть отклонения)
);
/* Получение состояния структуры цены проекта/этапа проекта */
function INFO_COST_STATUS_GET
(
NPROJECT in number, -- Рег. номер проекта
NPROJECTSTAGE in number := null -- Рег. номер этапа (null - по всем)
) return number; -- Состояние структуры цены (-1 - не определено, 0 - без отклонений, 1 - есть статьи с расходом больше 90%, 2 - есть статьи с перерасходом)
/* Получение % готовности проекта/этапа проекта (по затратам) */
function INFO_COST_READY_GET
(
NPROJECT in number, -- Рег. номер проекта
NPROJECTSTAGE in number := null -- Рег. номер этапа (null - по всем)
) return number; -- % готовности
/* Подбор записей журнала затрат (факт) */
procedure INFO_FCCOSTNOTES_FACT_SELECT
(
NFACEACC in number, -- Рег. номер лицевого счета
NFPDARTCL in number, -- Рег. номер статьи затрат
NIDENT out number -- Идентификатор буфера подобранных (списка отмеченных записей, null - не найдено)
);
/* Поиск активной структуры цены (утвеждена или согласована, актуальна по датам, активна) */
function INFO_CONTRPRSTRUCT_ACTIVE_FIND
(
NPROJECTSTAGE in number -- Рег. номер этапа проекта
) return number; -- Рег. номер записи структуры цены
/* Список проектов (таблица данных) */
procedure INFO_PROJECTS_DG
(
SPRJ_TYPE in varchar2 := null, -- Мнемокод типа проекта
SINS_DEPARTMENT in varchar2 := null, -- Мнемокод штатного подразделения
NCOST_STATUS in number := 0, -- Статус структуры цены (0 - все, 1 - есть статьи с расходом больше 90%, 2 - есть статьи с перерасходом)
NSTATE in number := 0, -- Состояние (0 - все, 1 - открытые, 2 - неоткрытые, т.е. с прочими статусами)
SSEARCH in varchar2 := null, -- Строка поиска
NPAGE_NUMBER in number, -- Номер страницы (игнорируется при NPAGE_SIZE=0)
NPAGE_SIZE in number, -- Количество записей на странице (0 - все)
CORDERS in clob, -- Сортировки
NINCLUDE_DEF in number, -- Признак включения описания колонок таблицы в ответ
COUT out clob -- Сериализованная таблица данных
);
/* Список этапов проекта (таблица данных) */
procedure INFO_STAGES_DG
(
NPROJECT in number, -- Рег. номер проекта
NPAGE_NUMBER in number, -- Номер страницы (игнорируется при NPAGE_SIZE=0)
NPAGE_SIZE in number, -- Количество записей на странице (0 - все)
CORDERS in clob, -- Сортировки
NINCLUDE_DEF in number, -- Признак включения описания колонок таблицы в ответ
COUT out clob -- Сериализованная таблица данных
);
/* Информация об этапе проекта (таблица данных) */
procedure INFO_STAGE_DTL_DG
(
NPROJECTSTAGE in number, -- Рег. номер этапа проекта
COUT out clob -- Сериализованная таблица данных
);
/* Структура цены этапа проекта (состав статей) */
procedure INFO_STAGE_ARTS_GET
(
NPROJECTSTAGE in number, -- Рег. номер этапа проекта
RINFO_STAGE_ARTS out TINFO_STAGE_ARTS -- Список статей структуры цены этапа проекта
);
/* Структура цены этапа проекта (таблица данных) */
procedure INFO_STAGE_ARTS_DG
(
NPROJECTSTAGE in number, -- Рег. номер этапа проекта
COUT out clob -- Сериализованная таблица данных
);
/* Структура цены этапа проекта (график) */
procedure INFO_STAGE_ARTS_CHART
(
NPROJECTSTAGE in number, -- Рег. номер этапа проекта
NTYPE in number, -- Тип диаграммы (0 - по плану, 1 - по факту)
COUT out clob -- Сериализованный график
);
end PKG_P8PANELS_PROJECTS;
/
create or replace package body PKG_P8PANELS_PROJECTS as
/* Константы - предопределённые значения */
SYES constant PKG_STD.TSTRING := 'Да'; -- Да
NDAYS_LEFT_LIMIT constant PKG_STD.TNUMBER := 30; -- Лимит отстатка дней для контроля сроков
SFPDARTCL_REALIZ constant PKG_STD.TSTRING := '14 Цена без НДС'; -- Мнемокод статьи калькуляции для учёта реализации
SFPDARTCL_SELF_COST constant PKG_STD.TSTRING := '10 Себестоимость'; -- Мнемокод статьи калькуляции для учёта себестоимости
NGANTT_TASK_CAPTION_LEN constant PKG_STD.TNUMBER := 50; -- Предельная длина (знаков) метки задачи при отображении диаграммы Ганта
NJB_DURATION_MEAS constant PKG_STD.TNUMBER := 0; -- Единица измерения длительности по умолчанию для интерфейса балансировки работ (0 - день, 1 - неделя, 2 - декада, 3 - месяц, 4 - квартал, 5 - год)
SJB_LAB_MEAS constant PKG_STD.TSTRING := 'Ч/Ч'; -- Единица измерения трудоёмкости по умолчанию для интерфейса балансировки работ
SLAB_MEAS_HOURS constant PKG_STD.TSTRING := 'Ч/Ч'; -- Единица измерения трудоёмкости в человеко/часах
/* Константы - дополнительные свойства */
SDP_SECON_RESP constant PKG_STD.TSTRING := 'ПУП.SECON_RESP'; -- Ответственный экономист проекта
SDP_STAX_GROUP constant PKG_STD.TSTRING := 'ПУП.TAX_GROUP'; -- Налоговая группа проекта
SDP_SCTL_COST constant PKG_STD.TSTRING := 'ПУП.CTL_COST'; -- Принзнак необходимости контроля факт. затрат по статье калькуляции
SDP_SCTL_CONTR constant PKG_STD.TSTRING := 'ПУП.CTL_CONTR'; -- Принзнак необходимости контроля контрактации по статье калькуляции
/* Считывание наименование подразделения по рег. номеру */
function UTL_INS_DEPARTMENT_GET_NAME
(
NRN in number -- Рег. номер подразделения
) return varchar2 -- Наименование подразеления (null - если не нашли)
is
SRES PKG_STD.TSTRING; -- Буфер для результата
begin
select T.NAME into SRES from INS_DEPARTMENT T where T.RN = NRN;
return SRES;
exception
when NO_DATA_FOUND then
return null;
end UTL_INS_DEPARTMENT_GET_NAME;
/* Считывание записи проекта */
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;
/* Проверка пользователя на ответственность за проект */
function CHECK_RESPONSIBLE
(
NRN in number, -- Рег. номер проекта
SAUTHID in varchar2 -- Имя пользователя
) return number -- Признак ответственности за проект (0 - не ответственный, 1 - ответственный)
is
RP PROJECT%rowtype; -- Запись проекта
NRES PKG_STD.TNUMBER := 0; -- Буфер для результата
NAUTHID_AGENT PKG_STD.TREF; -- Рег. номер контрагента пользователя
begin
/* Считаем проект */
RP := GET(NRN => NRN);
/* Найдем контрагента, соответствующего текущему пользователю */
FIND_AGNLIST_AUTHID(NFLAG_OPTION => 1, NCOMPANY => RP.COMPANY, SPERS_AUTHID => SAUTHID, NAGENT => NAUTHID_AGENT);
/* Проверим ответственность */
if (RP.RESPONSIBLE = NAUTHID_AGENT) then
NRES := 1;
end if;
/* Вернём результат */
return NRES;
exception
when others then
return NRES;
end CHECK_RESPONSIBLE;
/* Отбор проектов */
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_SQL_BUILD.PKG_NAME(SNAME => '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_SQL_BUILD.PKG_NAME(SNAME => '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_SQL_BUILD.PKG_NAME(SNAME => '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_SQL_BUILD.PKG_NAME(SNAME => '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_SQL_BUILD.PKG_NAME(SNAME => '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_SQL_BUILD.PKG_NAME(SNAME => '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;
/* Готовность (%, по затратам) */
if ((PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'EDCOST_READYFrom') = 1) and
(PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'EDCOST_READYTo') = 0)) then
PKG_COND_BROKER.ADD_CLAUSE(SCLAUSE => PKG_SQL_BUILD.PKG_NAME(SNAME => 'PKG_P8PANELS_PROJECTS.GET_COST_READY') ||
'(RN) >= :EDCOST_READYFrom');
PKG_COND_BROKER.BIND_VARIABLE(SVARIABLE_NAME => 'EDCOST_READYFrom',
NVALUE => PKG_COND_BROKER.GET_CONDITION_NUM(SCONDITION_NAME => 'EDCOST_READYFrom'));
end if;
if ((PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'EDCOST_READYTo') = 1) and
(PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'EDCOST_READYFrom') = 0)) then
PKG_COND_BROKER.ADD_CLAUSE(SCLAUSE => PKG_SQL_BUILD.PKG_NAME(SNAME => 'PKG_P8PANELS_PROJECTS.GET_COST_READY') ||
'(RN) <= :EDCOST_READYTo');
PKG_COND_BROKER.BIND_VARIABLE(SVARIABLE_NAME => 'EDCOST_READYTo',
NVALUE => PKG_COND_BROKER.GET_CONDITION_NUM(SCONDITION_NAME => 'EDCOST_READYTo'));
end if;
if ((PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'EDCOST_READYFrom') = 1) and
(PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'EDCOST_READYTo') = 1)) then
PKG_COND_BROKER.ADD_CLAUSE(SCLAUSE => PKG_SQL_BUILD.PKG_NAME(SNAME => 'PKG_P8PANELS_PROJECTS.GET_COST_READY') ||
'(RN) between :EDCOST_READYFrom and :EDCOST_READYTo');
PKG_COND_BROKER.BIND_VARIABLE(SVARIABLE_NAME => 'EDCOST_READYFrom',
NVALUE => PKG_COND_BROKER.GET_CONDITION_NUM(SCONDITION_NAME => 'EDCOST_READYFrom'));
PKG_COND_BROKER.BIND_VARIABLE(SVARIABLE_NAME => 'EDCOST_READYTo',
NVALUE => PKG_COND_BROKER.GET_CONDITION_NUM(SCONDITION_NAME => 'EDCOST_READYTo'));
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
and exists (select null from V_USERPRIV UP where UP.CATALOG = PS.CRN)
and exists (select null
from V_USERPRIV UP
where UP.JUR_PERS = PS.JUR_PERS
and UP.UNITCODE = 'Projects')
and exists (select /*+ INDEX(UP I_USERPRIV_CATALOG_ROLEID) */
null
from USERPRIV UP
where UP.CATALOG = CN.CRN
and UP.ROLEID in (select /*+ INDEX(UR I_USERROLES_AUTHID_FK) */
UR.ROLEID
from USERROLES UR
where UR.AUTHID = UTILIZER)
union all
select /*+ INDEX(UP I_USERPRIV_CATALOG_AUTHID) */
null
from USERPRIV UP
where UP.CATALOG = CN.CRN
and UP.AUTHID = UTILIZER)
and exists (select /*+ INDEX(UP I_USERPRIV_JUR_PERS_ROLEID) */
null
from USERPRIV UP
where UP.JUR_PERS = CN.JUR_PERS
and UP.UNITCODE = 'Contracts'
and UP.ROLEID in (select /*+ INDEX(UR I_USERROLES_AUTHID_FK) */
UR.ROLEID
from USERROLES UR
where UR.AUTHID = UTILIZER)
union all
select /*+ INDEX(UP I_USERPRIV_JUR_PERS_AUTHID) */
null
from USERPRIV UP
where UP.JUR_PERS = CN.JUR_PERS
and UP.UNITCODE = 'Contracts'
and UP.AUTHID = UTILIZER)
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
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_FIN(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_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
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_COEXEC(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_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
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_ACT(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_ACT;
/* Получение % готовности проекта (по затратам) */
function GET_COST_READY
(
NRN in number -- Рег. номер проекта
) return number -- % готовности
is
RP PROJECT%rowtype; -- Запись проекта
NFPDARTCL_SELF_COST PKG_STD.TREF; -- Рег. номер статьи себестоимости
NCOST_FACT PKG_STD.TNUMBER := 0; -- Сумма фактических затрат по проекту
NSELF_COST_PLAN PKG_STD.TNUMBER := 0; -- Плановая себестоимость проекта
RSTG_SELF_COST_PLAN TSTAGE_ARTS; -- Плановая себестоимость этапа
NRES PKG_STD.TNUMBER := 0; -- Буфер для результата
begin
/* Читаем проект */
RP := GET(NRN => NRN);
/* Определим рег. номер статьи калькуляции для учёта себестоимости */
FIND_FPDARTCL_CODE(NFLAG_SMART => 1,
NCOMPANY => RP.COMPANY,
SCODE => SFPDARTCL_SELF_COST,
NRN => NFPDARTCL_SELF_COST);
/* Обходим этапы */
for C in (select PS.RN from PROJECTSTAGE PS where PS.PRN = RP.RN)
loop
/* Накапливаем сумму фактических затрат */
NCOST_FACT := NCOST_FACT + STAGES_GET_COST_FACT(NRN => C.RN);
/* Накапливаем плановую себестоимость */
STAGE_ARTS_GET(NSTAGE => C.RN, NFPDARTCL => NFPDARTCL_SELF_COST, RSTAGE_ARTS => RSTG_SELF_COST_PLAN);
if ((RSTG_SELF_COST_PLAN.COUNT = 1) and (RSTG_SELF_COST_PLAN(RSTG_SELF_COST_PLAN.LAST).NPLAN <> 0)) then
NSELF_COST_PLAN := NSELF_COST_PLAN + RSTG_SELF_COST_PLAN(RSTG_SELF_COST_PLAN.LAST).NPLAN;
end if;
end loop;
/* Если есть и фактические затраты и плановая себестоимость */
if ((NCOST_FACT > 0) and (NSELF_COST_PLAN > 0)) then
/* Отношение фактических затрат к плановой себестоимость - искомый % готовности */
NRES := ROUND(NCOST_FACT / NSELF_COST_PLAN * 100, 0);
/* Если затраты превысили себестоимость, то % может быть > 100, но это бессмысленно, откорректируем ситуацию */
if (NRES > 100) then
NRES := 100;
end if;
end if;
/* Вернём рассчитанное */
return NRES;
end GET_COST_READY;
/* Список проектов */
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.TDG_FILTERS; -- Фильтры
RO PKG_P8PANELS_VISUAL.TDG_ORDERS; -- Сортировки
RDG PKG_P8PANELS_VISUAL.TDG; -- Описание таблицы
RDG_ROW PKG_P8PANELS_VISUAL.TDG_ROW; -- Строка таблицы
RCOL_VALS PKG_P8PANELS_VISUAL.TDG_COL_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.TDG_FILTERS_FROM_XML(CFILTERS => CFILTERS);
/* Читаем сортировки */
RO := PKG_P8PANELS_VISUAL.TDG_ORDERS_FROM_XML(CORDERS => CORDERS);
/* Преобразуем номер и размер страницы в номер строк с и по */
PKG_P8PANELS_VISUAL.UTL_ROWS_LIMITS_CALC(NPAGE_NUMBER => NPAGE_NUMBER,
NPAGE_SIZE => NPAGE_SIZE,
NROW_FROM => NROW_FROM,
NROW_TO => NROW_TO);
/* Инициализируем таблицу данных */
RDG := PKG_P8PANELS_VISUAL.TDG_MAKE();
/* Добавляем в таблицу описание колонок */
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NRN',
SCAPTION => 'Рег. номер',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_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.TDG_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.TDG_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.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SEXPECTED_RES',
SCAPTION => 'Ожидаемые результаты',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_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.TDG_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.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SGOVCNTRID',
SCAPTION => 'ИГК',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SDOC_OSN',
SCAPTION => 'Документ-основание',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_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.TDG_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.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SSUBDIV_RESP',
SCAPTION => 'Подразделение-исполнитель',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SRESPONSIBLE',
SCAPTION => 'Ответственный исполнитель',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SECON_RESP',
SCAPTION => 'Ответственный экономист',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_COL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 0, BCLEAR => true);
PKG_P8PANELS_VISUAL.TDG_COL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 1);
PKG_P8PANELS_VISUAL.TDG_COL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 2);
PKG_P8PANELS_VISUAL.TDG_COL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 3);
PKG_P8PANELS_VISUAL.TDG_COL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 4);
PKG_P8PANELS_VISUAL.TDG_COL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 5);
PKG_P8PANELS_VISUAL.TDG_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.TDG_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.TDG_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.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NCOST_SUM',
SCAPTION => 'Стоимость',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SCURNAMES',
SCAPTION => 'Валюта',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NFIN_IN',
SCAPTION => 'Входящее финансирование',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_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.TDG_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.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NFIN_OUT',
SCAPTION => 'Исходящее финансирование',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_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.TDG_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.TDG_COL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 0, BCLEAR => true);
PKG_P8PANELS_VISUAL.TDG_COL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 1);
PKG_P8PANELS_VISUAL.TDG_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,
SHINT => '<b>Финансирование (исходящее)</b> - контроль оплаты счетов, выставленных соисполнителями в рамках проекта.<br>' ||
'<b style="color:red">Требует внимания</b> - в проекте есть этапы, для которых не все выставленные соисполнителями счета оплачены.<br>' ||
'<b style="color:green">В норме</b> - нет этапов с отклонениями, описанными выше.<br>' ||
'<b style="color:gray">Пусто</b> - в Системе не хватает данных для рассчёта. Убедитесь, что для этапов задана привязка к договорам с соисполнителями.');
PKG_P8PANELS_VISUAL.TDG_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,
SHINT => '<b>Контрактация</b> - контроль суммы договоров, заключеных с соисполнителями в рамках проекта.<br>' ||
'<b style="color:red">Требует внимания</b> - в проекте есть этапы, для которых сумма договоров с соисполнителями превышает заложенные в калькуляцию плановые показатели.<br>' ||
'<b style="color:green">В норме</b> - нет этапов с отклонениями, описанными выше.<br>' ||
'<b style="color:gray">Пусто</b> - в Системе не хватает данных для рассчёта. Убедитесь, что для всех этапов заданы плановые калькуляции.');
PKG_P8PANELS_VISUAL.TDG_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,
SHINT => '<b>Соисполнение</b> - контроль исполнения обязательств по договорам, заключеным с соисполнителями в рамках проекта.<br>' ||
'<b style="color:red">Требует внимания</b> - в проекте есть этапы, до окончания которых осталось менее ' ||
TO_CHAR(NDAYS_LEFT_LIMIT) ||
' дней, при этом зафиксирован положительный остаток к поставке/актированию по договорам соисполнителей данного этапа.<br>' ||
'<b style="color:green">В норме</b> - нет этапов с отклонениями, описанными выше.<br>' ||
'<b style="color:gray">Пусто</b> - в Системе не хватает данных для рассчёта. Убедитесь, что для этапов задана привязка к договорам с соисполнителями и плановые сроки окончания.');
PKG_P8PANELS_VISUAL.TDG_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,
SHINT => '<b>Сроки</b> - контроль сроков исполнения работ по проекту.<br>' ||
'<b style="color:red">Требует внимания</b> - в проекте есть этапы, до окончания которых осталось менее ' ||
TO_CHAR(NDAYS_LEFT_LIMIT) || ' дней.<br>' ||
'<b style="color:green">В норме</b> - нет этапов с отклонениями, описанными выше.<br>' ||
'<b style="color:gray">Пусто</b> - в Системе не хватает данных для рассчёта. Убедитесь, что для этапов заданы плановые сроки окончания.');
PKG_P8PANELS_VISUAL.TDG_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,
SHINT => '<b>Затраты</b> - контроль затрат, понесённых в ходе выполнения работ по проекту.<br>' ||
'<b style="color:red">Требует внимания</b> - в проекте есть этапы, для которых сумма фактических затрат по статьям калькуляции превысила плановую.<br>' ||
'<b style="color:green">В норме</b> - нет этапов с отклонениями, описанными выше.<br>' ||
'<b style="color:gray">Пусто</b> - в Системе не хватает данных для рассчёта. Убедитесь, что для этапов задана действующая калькуляция с указанием плановых значений по статьям, подлежащим контролю.');
PKG_P8PANELS_VISUAL.TDG_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,
SHINT => '<b>Актирование</b> - контроль актирования работ, выполненных по проекту, со стороны заказчика.<br>' ||
'<b style="color:red">Требует внимания</b> - в проекте есть этапы, в состоянии "Закрыт", но при этом в Системе отсутствует утверждённая "Расходная накладная на отпуск потребителю" для данного этапа.<br>' ||
'<b style="color:green">В норме</b> - нет этапов с отклонениями, описанными выше.<br>' ||
'<b style="color:gray">Пусто</b> - в Системе не хватает данных для рассчёта. Убедитесь, что этапы, по которым завершены работы, переведены в состояние "Закрыт".');
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NCOST_READY',
SCAPTION => 'Готов (%, затраты)',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
SCOND_FROM => 'EDCOST_READYFrom',
SCOND_TO => 'EDCOST_READYTo',
BORDER => true,
BFILTER => true);
/* Определим дополнительные свойства - ответственный экономист */
FIND_DOCS_PROPS_CODE(NFLAG_SMART => 1, NCOMPANY => NCOMPANY, SCODE => SDP_SECON_RESP, NRN => NECON_RESP_DP);
/* Обходим данные */
begin
/* Добавляем подсказку совместимости */
CSQL := PKG_SQL_BUILD.COMPATIBLE(SSQL => CSQL);
/* Формируем запрос */
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => 'select *');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from (select D.*,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.SQLROWNUM() || ' NROW');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from (select P.RN NRN,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' P.CODE SCODE,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' P."NAME" SNAME,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' P.NAME_USL SNAME_USL,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' P.EXPECTED_RES SEXPECTED_RES,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' PT.CODE SPRJTYPE,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' EC.AGNABBR SEXT_CUST,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' GC.CODE SGOVCNTRID,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' P.DOC_OSN SDOC_OSN,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.WRAP_STR(SVALUE => 'Contracts') || ' SLNK_UNIT_SDOC_OSN,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.PKG_NAME(SNAME => 'PKG_P8PANELS_PROJECTS.GET_DOC_OSN_LNK_DOCUMENT') || '(P.RN) NLNK_DOCUMENT_SDOC_OSN,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' SR.CODE SSUBDIV_RESP,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' R.AGNABBR SRESPONSIBLE,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' F_DOCS_PROPS_GET_STR_VALUE(:NECON_RESP_DP, ' || PKG_SQL_BUILD.WRAP_STR(SVALUE => 'Projects') || ', P.RN) SECON_RESP,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' P."STATE" NSTATE,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' P.BEGPLAN DBEGPLAN,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' P.ENDPLAN DENDPLAN,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' P.COST_SUM_BASECURR NCOST_SUM,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' CN.INTCODE SCURNAMES,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.PKG_NAME(SNAME => 'PKG_P8PANELS_PROJECTS.GET_FIN_IN') || '(P.RN) NFIN_IN,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.WRAP_STR(SVALUE => 'Paynotes') || ' SLNK_UNIT_NFIN_IN,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.WRAP_NUM(NVALUE => 0) || ' NLNK_DOCUMENT_NFIN_IN,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.PKG_NAME(SNAME => 'PKG_P8PANELS_PROJECTS.GET_FIN_OUT') || '(P.RN) NFIN_OUT,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.WRAP_STR(SVALUE => 'Paynotes') || ' SLNK_UNIT_NFIN_OUT,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.WRAP_NUM(NVALUE => 1) || ' NLNK_DOCUMENT_NFIN_OUT,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.PKG_NAME(SNAME => 'PKG_P8PANELS_PROJECTS.GET_CTRL_FIN') || '(P.RN) NCTRL_FIN,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.PKG_NAME(SNAME => 'PKG_P8PANELS_PROJECTS.GET_CTRL_CONTR') || '(P.RN) NCTRL_CONTR,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.PKG_NAME(SNAME => 'PKG_P8PANELS_PROJECTS.GET_CTRL_COEXEC') || '(P.RN) NCTRL_COEXEC,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.PKG_NAME(SNAME => 'PKG_P8PANELS_PROJECTS.GET_CTRL_PERIOD') || '(P.RN) NCTRL_PERIOD,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.PKG_NAME(SNAME => 'PKG_P8PANELS_PROJECTS.GET_CTRL_COST') || '(P.RN) NCTRL_COST,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.PKG_NAME(SNAME => 'PKG_P8PANELS_PROJECTS.GET_CTRL_ACT') || '(P.RN) NCTRL_ACT,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.PKG_NAME(SNAME => 'PKG_P8PANELS_PROJECTS.GET_COST_READY') || '(P.RN) NCOST_READY');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from PROJECT P');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' left outer join AGNLIST EC on P.EXT_CUST = EC.RN');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' left outer join GOVCNTRID GC on P.GOVCNTRID = GC.RN');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' left outer join INS_DEPARTMENT SR on P.SUBDIV_RESP = SR.RN');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' left outer join AGNLIST R on P.RESPONSIBLE = R.RN,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' PRJTYPE PT,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' CURNAMES CN');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' where P.PRJTYPE = PT.RN');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and P.CURNAMES = CN.RN');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and exists (select null from V_USERPRIV UP where UP."CATALOG" = P.CRN)');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and exists (select null from V_USERPRIV UP where UP.JUR_PERS = P.JUR_PERS and UP.UNITCODE = ' || PKG_SQL_BUILD.WRAP_STR(SVALUE => 'Projects') || ')');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and P.RN in (select ID from COND_BROKER_IDSMART where IDENT = :NIDENT) %ORDER_BY%) D) F');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' where F.NROW between :NROW_FROM and :NROW_TO');
/* Учтём сортировки */
PKG_P8PANELS_VISUAL.TDG_ORDERS_SET_QUERY(RDATA_GRID => RDG,
RORDERS => RO,
SPATTERN => '%ORDER_BY%',
CSQL => CSQL);
/* Учтём фильтры */
PKG_P8PANELS_VISUAL.TDG_FILTERS_SET_QUERY(NIDENT => NIDENT,
NCOMPANY => NCOMPANY,
SUNIT => 'Projects',
SPROCEDURE => PKG_SQL_BUILD.PKG_NAME(SNAME => '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);
PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 32);
PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 33);
/* Делаем выборку */
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.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NRN',
ICURSOR => ICURSOR,
NPOSITION => 1,
BCLEAR => true);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SCODE', ICURSOR => ICURSOR, NPOSITION => 2);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SNAME', ICURSOR => ICURSOR, NPOSITION => 3);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SNAME_USL',
ICURSOR => ICURSOR,
NPOSITION => 4);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SEXPECTED_RES',
ICURSOR => ICURSOR,
NPOSITION => 5);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SPRJTYPE',
ICURSOR => ICURSOR,
NPOSITION => 6);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SEXT_CUST',
ICURSOR => ICURSOR,
NPOSITION => 7);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SGOVCNTRID',
ICURSOR => ICURSOR,
NPOSITION => 8);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SDOC_OSN',
ICURSOR => ICURSOR,
NPOSITION => 9);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SLNK_UNIT_SDOC_OSN',
ICURSOR => ICURSOR,
NPOSITION => 10);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NLNK_DOCUMENT_SDOC_OSN',
ICURSOR => ICURSOR,
NPOSITION => 11);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SSUBDIV_RESP',
ICURSOR => ICURSOR,
NPOSITION => 12);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SRESPONSIBLE',
ICURSOR => ICURSOR,
NPOSITION => 13);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SECON_RESP',
ICURSOR => ICURSOR,
NPOSITION => 14);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NSTATE',
ICURSOR => ICURSOR,
NPOSITION => 15);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLD(RROW => RDG_ROW,
SNAME => 'DBEGPLAN',
ICURSOR => ICURSOR,
NPOSITION => 16);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLD(RROW => RDG_ROW,
SNAME => 'DENDPLAN',
ICURSOR => ICURSOR,
NPOSITION => 17);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NCOST_SUM',
ICURSOR => ICURSOR,
NPOSITION => 18);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SCURNAMES',
ICURSOR => ICURSOR,
NPOSITION => 19);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NFIN_IN',
ICURSOR => ICURSOR,
NPOSITION => 20);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SLNK_UNIT_NFIN_IN',
ICURSOR => ICURSOR,
NPOSITION => 21);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NLNK_DOCUMENT_NFIN_IN',
ICURSOR => ICURSOR,
NPOSITION => 22);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NFIN_OUT',
ICURSOR => ICURSOR,
NPOSITION => 23);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SLNK_UNIT_NFIN_OUT',
ICURSOR => ICURSOR,
NPOSITION => 24);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NLNK_DOCUMENT_NFIN_OUT',
ICURSOR => ICURSOR,
NPOSITION => 25);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NCTRL_FIN',
ICURSOR => ICURSOR,
NPOSITION => 26);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NCTRL_CONTR',
ICURSOR => ICURSOR,
NPOSITION => 27);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NCTRL_COEXEC',
ICURSOR => ICURSOR,
NPOSITION => 28);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NCTRL_PERIOD',
ICURSOR => ICURSOR,
NPOSITION => 29);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NCTRL_COST',
ICURSOR => ICURSOR,
NPOSITION => 30);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NCTRL_ACT',
ICURSOR => ICURSOR,
NPOSITION => 31);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NCOST_READY',
ICURSOR => ICURSOR,
NPOSITION => 32);
/* Добавляем строку в таблицу */
PKG_P8PANELS_VISUAL.TDG_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
end loop;
/* Освобождаем курсор */
PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR);
exception
when others then
PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR);
raise;
end;
/* Сериализуем описание */
COUT := PKG_P8PANELS_VISUAL.TDG_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => NINCLUDE_DEF);
end LIST;
/* Сфодный график проектов */
procedure GRAPH
(
COUT out clob -- График проектов
)
is
NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Рег. номер организации
DFROM PKG_STD.TLDATE; -- Дата начала всех работ
DTO PKG_STD.TLDATE; -- Дата окончания всех работ
DFROM_CUR PKG_STD.TLDATE; -- Дата начала текущая
DTO_CUR PKG_STD.TLDATE; -- Дата окончания текущая
SYEAR_COL_NAME PKG_STD.TSTRING; -- Наименование колонки для года
SPRJ_GROUP_NAME PKG_STD.TSTRING; -- Наименование группы для проекта
BEXPANDED boolean; -- Флаг раскрытости уровня
RDG PKG_P8PANELS_VISUAL.TDG; -- Описание таблицы
RDG_ROW PKG_P8PANELS_VISUAL.TDG_ROW; -- Строка таблицы
begin
/* Определим даты начала и окончания проектов */
select TRUNC(min(DBEGPLAN), 'mm'),
LAST_DAY(max(DENDPLAN))
into DFROM,
DTO
from (select min(P.BEGPLAN) DBEGPLAN,
max(P.ENDPLAN) DENDPLAN
from PROJECT P
where P.COMPANY = NCOMPANY
and P.STATE in (0, 1, 4)
and P.BEGPLAN is not null
and P.ENDPLAN is not null
union all
select min(PS.BEGPLAN) DBEGPLAN,
max(PS.ENDPLAN) DENDPLAN
from PROJECT P,
PROJECTSTAGE PS
where P.COMPANY = NCOMPANY
and P.STATE in (0, 1, 4)
and P.RN = PS.PRN
and PS.STATE in (0, 1, 3)
and PS.BEGPLAN is not null
and PS.ENDPLAN is not null
and PS.HRN is null);
/* Инициализируем таблицу данных */
RDG := PKG_P8PANELS_VISUAL.TDG_MAKE(BFIXED_HEADER => true, NFIXED_COLUMNS => 1);
/* Если есть данные о начале и окончании проектов в портфеле */
if ((DFROM is not null) and (DTO is not null)) then
/* Формируем структуру заголовка */
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NRN',
SCAPTION => 'Рег. номер',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SJOB',
SCAPTION => 'Работы',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
NWIDTH => 300);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SRESP',
SCAPTION => 'Ответственный',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NSTATE',
SCAPTION => 'Состояние',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'DFROM',
SCAPTION => 'Начало работы',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_DATE,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'DTO',
SCAPTION => 'Окончание работы',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_DATE,
BVISIBLE => false);
for Y in EXTRACT(year from DFROM) .. EXTRACT(year from DTO)
loop
SYEAR_COL_NAME := TO_CHAR(Y);
if (Y = EXTRACT(year from sysdate)) then
BEXPANDED := true;
else
BEXPANDED := false;
end if;
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => SYEAR_COL_NAME,
SCAPTION => TO_CHAR(Y),
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BEXPANDABLE => true,
BEXPANDED => BEXPANDED);
for M in 1 .. 12
loop
DFROM_CUR := TO_DATE('01.' || LPAD(TO_CHAR(M), 2, '0') || '.' || TO_CHAR(Y), 'dd.mm.yyyy');
DTO_CUR := LAST_DAY(DFROM_CUR);
if ((DFROM_CUR >= DFROM) and (DTO_CUR <= DTO)) then
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => SYEAR_COL_NAME || '_' || TO_CHAR(M),
SCAPTION => LPAD(TO_CHAR(M), 2, '0'),
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
SPARENT => SYEAR_COL_NAME);
end if;
end loop;
end loop;
/* Обходим открытые проекты */
for PR in (select P.*
from PROJECT P
where P.COMPANY = NCOMPANY
and P.STATE in (0, 1, 4)
and P.BEGPLAN is not null
and P.ENDPLAN is not null
order by P.BEGPLAN)
loop
/* Добвим группу для проекта */
SPRJ_GROUP_NAME := PR.RN;
PKG_P8PANELS_VISUAL.TDG_ADD_GROUP(RDATA_GRID => RDG,
SNAME => SPRJ_GROUP_NAME,
SCAPTION => PR.CODE || ' - ' || PR.NAME,
BEXPANDABLE => true,
BEXPANDED => true);
/* Обходим этапы проекта */
for ST in (select PS.RN NRN,
trim(PS.NUMB) || ' - ' || PS.NAME SJOB,
COALESCE(AG.AGNABBR, IND.NAME) SRESP,
PS.STATE NSTATE,
PS.BEGPLAN DFROM,
PS.ENDPLAN DTO
from PROJECTSTAGE PS,
AGNLIST AG,
INS_DEPARTMENT IND
where PS.PRN = PR.RN
and PS.STATE in (0, 1, 3)
and PS.BEGPLAN is not null
and PS.ENDPLAN is not null
and PS.HRN is null
and PS.RESPONSIBLE = AG.RN(+)
and PS.SUBDIV_RESP = IND.RN(+)
order by PS.NUMB)
loop
/* Инициализируем строку */
RDG_ROW := PKG_P8PANELS_VISUAL.TDG_ROW_MAKE(SGROUP => SPRJ_GROUP_NAME);
/* Добавляем колонки с данными */
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NRN', NVALUE => ST.NRN);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SJOB', SVALUE => ST.SJOB);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SRESP', SVALUE => ST.SRESP);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NSTATE', NVALUE => ST.NSTATE);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'DFROM', DVALUE => ST.DFROM);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'DTO', DVALUE => ST.DTO);
/* Добавим строку для этапа */
PKG_P8PANELS_VISUAL.TDG_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
end loop;
end loop;
end if;
/* Сериализуем описание */
COUT := PKG_P8PANELS_VISUAL.TDG_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => 1);
end GRAPH;
/* График по данным проектов - "Топ проблем" */
procedure CHART_PROBLEMS
(
COUT out clob -- Сериализованный график
)
is
NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса
RCH PKG_P8PANELS_VISUAL.TCHART; -- График
RCH_DS PKG_P8PANELS_VISUAL.TCHART_DATASET; -- Набор данных
RATTR_VALS PKG_P8PANELS_VISUAL.TCHART_DATASET_ITEM_ATTR_VALS; -- Атрибуты элемента набора данных
begin
/* Сформируем заголовок графика */
RCH := PKG_P8PANELS_VISUAL.TCHART_MAKE(STYPE => PKG_P8PANELS_VISUAL.SCHART_TYPE_BAR,
STITLE => 'Топ проблем',
SLGND_POS => PKG_P8PANELS_VISUAL.SCHART_LGND_POS_TOP);
/* Сформируем набор данных */
RCH_DS := PKG_P8PANELS_VISUAL.TCHART_DATASET_MAKE(SCAPTION => 'Кол-во проектов с проблемой');
/* Строим список проблем по убыванию количества */
for C in (select D.SFILTER,
D.SNAME,
D.NCOUNT
from (select 'NCTRL_FIN' SFILTER,
'Финансирование' SNAME,
count(P.RN) NCOUNT
from PROJECT P
where P.COMPANY = NCOMPANY
and PKG_P8PANELS_PROJECTS.GET_CTRL_FIN(P.RN) = 1
and exists (select null from V_USERPRIV UP where UP.CATALOG = P.CRN)
and exists (select null
from V_USERPRIV UP
where UP.JUR_PERS = P.JUR_PERS
and UP.UNITCODE = 'Projects')
union all
select 'NCTRL_CONTR' SFILTER,
'Контрактация' SNAME,
count(P.RN) NCOUNT
from PROJECT P
where P.COMPANY = NCOMPANY
and PKG_P8PANELS_PROJECTS.GET_CTRL_CONTR(P.RN) = 1
and exists (select null from V_USERPRIV UP where UP.CATALOG = P.CRN)
and exists (select null
from V_USERPRIV UP
where UP.JUR_PERS = P.JUR_PERS
and UP.UNITCODE = 'Projects')
union all
select 'NCTRL_COEXEC' SFILTER,
'Соисполнение' SNAME,
count(P.RN) NCOUNT
from PROJECT P
where P.COMPANY = NCOMPANY
and PKG_P8PANELS_PROJECTS.GET_CTRL_COEXEC(P.RN) = 1
and exists (select null from V_USERPRIV UP where UP.CATALOG = P.CRN)
and exists (select null
from V_USERPRIV UP
where UP.JUR_PERS = P.JUR_PERS
and UP.UNITCODE = 'Projects')
union all
select 'NCTRL_PERIOD' SFILTER,
'Сроки' SNAME,
count(P.RN) NCOUNT
from PROJECT P
where P.COMPANY = NCOMPANY
and PKG_P8PANELS_PROJECTS.GET_CTRL_PERIOD(P.RN) = 1
and exists (select null from V_USERPRIV UP where UP.CATALOG = P.CRN)
and exists (select null
from V_USERPRIV UP
where UP.JUR_PERS = P.JUR_PERS
and UP.UNITCODE = 'Projects')
union all
select 'NCTRL_COST' SFILTER,
'Затраты' SNAME,
count(P.RN) NCOUNT
from PROJECT P
where P.COMPANY = NCOMPANY
and PKG_P8PANELS_PROJECTS.GET_CTRL_COST(P.RN) = 1
and exists (select null from V_USERPRIV UP where UP.CATALOG = P.CRN)
and exists (select null
from V_USERPRIV UP
where UP.JUR_PERS = P.JUR_PERS
and UP.UNITCODE = 'Projects')
union all
select 'NCTRL_ACT' SFILTER,
'Актирование' SNAME,
count(P.RN) NCOUNT
from PROJECT P
where P.COMPANY = NCOMPANY
and PKG_P8PANELS_PROJECTS.GET_CTRL_ACT(P.RN) = 1
and exists (select null from V_USERPRIV UP where UP.CATALOG = P.CRN)
and exists (select null
from V_USERPRIV UP
where UP.JUR_PERS = P.JUR_PERS
and UP.UNITCODE = 'Projects')) D
order by D.NCOUNT desc)
loop
/* Если проблема выявлена */
if (C.NCOUNT > 0) then
/* Добавим метку для проблемы */
PKG_P8PANELS_VISUAL.TCHART_ADD_LABEL(RCHART => RCH, SLABEL => C.SNAME);
/* Добавим проблему в набор данных */
PKG_P8PANELS_VISUAL.TCHART_DATASET_ITM_ATTR_VL_ADD(RATTR_VALS => RATTR_VALS,
SNAME => 'SFILTER',
SVALUE => C.SFILTER,
BCLEAR => true);
PKG_P8PANELS_VISUAL.TCHART_DATASET_ITM_ATTR_VL_ADD(RATTR_VALS => RATTR_VALS,
SNAME => 'SFILTER_VALUE',
SVALUE => '1');
PKG_P8PANELS_VISUAL.TCHART_DATASET_ADD_ITEM(RDATASET => RCH_DS, NVALUE => C.NCOUNT, RATTR_VALS => RATTR_VALS);
end if;
end loop;
/* Добавим набор данных в график */
PKG_P8PANELS_VISUAL.TCHART_ADD_DATASET(RCHART => RCH, RDATASET => RCH_DS);
/* Сериализуем описание */
COUT := PKG_P8PANELS_VISUAL.TCHART_TO_XML(RCHART => RCH, NINCLUDE_DEF => 1);
end CHART_PROBLEMS;
/* График по данным проектов - "Топ заказчиков" */
procedure CHART_CUSTOMERS
(
COUT out clob -- Сериализованный график
)
is
NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса
RCH PKG_P8PANELS_VISUAL.TCHART; -- График
RCH_DS PKG_P8PANELS_VISUAL.TCHART_DATASET; -- Набор данных
RATTR_VALS PKG_P8PANELS_VISUAL.TCHART_DATASET_ITEM_ATTR_VALS; -- Атрибуты элемента набора данных
begin
/* Сформируем заголовок графика */
RCH := PKG_P8PANELS_VISUAL.TCHART_MAKE(STYPE => PKG_P8PANELS_VISUAL.SCHART_TYPE_PIE,
STITLE => 'Топ заказчиков',
SLGND_POS => PKG_P8PANELS_VISUAL.SCHART_LGND_POS_RIGHT);
/* Сформируем набор данных */
RCH_DS := PKG_P8PANELS_VISUAL.TCHART_DATASET_MAKE(SCAPTION => 'Стоимость проектов');
/* Обходим проекты, сгруппированные по внешним заказчикам */
for C in (select D.SEXT_CUST,
D.NSUM
from (select EC.AGNABBR SEXT_CUST,
sum(P.COST_SUM_BASECURR) NSUM
from PROJECT P,
AGNLIST EC
where P.COMPANY = NCOMPANY
and P.EXT_CUST = EC.RN
group by EC.AGNABBR
order by 2 desc) D
where ROWNUM <= 5)
loop
/* Добавим метку для контрагента */
PKG_P8PANELS_VISUAL.TCHART_ADD_LABEL(RCHART => RCH, SLABEL => C.SEXT_CUST);
/* Добавим контрагента в набор данных */
PKG_P8PANELS_VISUAL.TCHART_DATASET_ITM_ATTR_VL_ADD(RATTR_VALS => RATTR_VALS,
SNAME => 'SFILTER',
SVALUE => 'SEXT_CUST',
BCLEAR => true);
PKG_P8PANELS_VISUAL.TCHART_DATASET_ITM_ATTR_VL_ADD(RATTR_VALS => RATTR_VALS,
SNAME => 'SFILTER_VALUE',
SVALUE => C.SEXT_CUST);
PKG_P8PANELS_VISUAL.TCHART_DATASET_ADD_ITEM(RDATASET => RCH_DS, NVALUE => C.NSUM, RATTR_VALS => RATTR_VALS);
end loop;
/* Добавим набор данных в график */
PKG_P8PANELS_VISUAL.TCHART_ADD_DATASET(RCHART => RCH, RDATASET => RCH_DS);
/* Сериализуем описание */
COUT := PKG_P8PANELS_VISUAL.TCHART_TO_XML(RCHART => RCH, NINCLUDE_DEF => 1);
end CHART_CUSTOMERS;
/* График по данным проектов - "Затраты на проекты" */
procedure CHART_FCCOSTNOTES
(
COUT out clob -- Сериализованный график
)
is
NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса
RCH PKG_P8PANELS_VISUAL.TCHART; -- График
RCH_DS PKG_P8PANELS_VISUAL.TCHART_DATASET; -- Набор данных
RATTR_VALS PKG_P8PANELS_VISUAL.TCHART_DATASET_ITEM_ATTR_VALS; -- Атрибуты элемента набора данных
NYEAR PKG_STD.TNUMBER; -- Текущий год
NSUM PKG_STD.TNUMBER; -- Сумма затрат в текущем месяце
begin
NYEAR := TO_NUMBER(TO_CHAR(sysdate, 'yyyy'));
/* Сформируем заголовок графика */
RCH := PKG_P8PANELS_VISUAL.TCHART_MAKE(STYPE => PKG_P8PANELS_VISUAL.SCHART_TYPE_LINE,
STITLE => 'Затраты на проекты в ' || TO_CHAR(NYEAR) || ' году',
SLGND_POS => PKG_P8PANELS_VISUAL.SCHART_LGND_POS_TOP);
/* Сформируем набор данных */
RCH_DS := PKG_P8PANELS_VISUAL.TCHART_DATASET_MAKE(SCAPTION => 'Сумма затрат (тыс. руб.)');
/* Обходим месяцы года */
for I in 1 .. 12
loop
/* Суммируем затраты этого месяца, отнесённые на проекты */
select COALESCE(sum(CN.COST_BSUM) / 1000, 0)
into NSUM
from FCCOSTNOTES CN
where CN.COMPANY = NCOMPANY
and TO_NUMBER(TO_CHAR(CN.COST_DATE, 'mm')) = I
and TO_NUMBER(TO_CHAR(CN.COST_DATE, 'yyyy')) = NYEAR
and exists (select null from V_USERPRIV UP where UP.CATALOG = CN.CRN)
and CN.PROD_ORDER in (select PS.FACEACC
from PROJECTSTAGE PS
where PS.COMPANY = CN.COMPANY
and exists (select null from V_USERPRIV UP where UP.CATALOG = PS.CRN)
and exists (select null
from V_USERPRIV UP
where UP.JUR_PERS = PS.JUR_PERS
and UP.UNITCODE = 'Projects'));
/* Добавим метку для месяца */
PKG_P8PANELS_VISUAL.TCHART_ADD_LABEL(RCHART => RCH, SLABEL => F_GET_MONTH(NVALUE => I));
/* Добавим месяц в набор данных */
PKG_P8PANELS_VISUAL.TCHART_DATASET_ITM_ATTR_VL_ADD(RATTR_VALS => RATTR_VALS,
SNAME => 'SUNITCODE',
SVALUE => 'CostNotes',
BCLEAR => true);
PKG_P8PANELS_VISUAL.TCHART_DATASET_ITM_ATTR_VL_ADD(RATTR_VALS => RATTR_VALS, SNAME => 'NYEAR', SVALUE => TO_CHAR(NYEAR));
PKG_P8PANELS_VISUAL.TCHART_DATASET_ITM_ATTR_VL_ADD(RATTR_VALS => RATTR_VALS, SNAME => 'NMONTH', SVALUE => TO_CHAR(I));
PKG_P8PANELS_VISUAL.TCHART_DATASET_ADD_ITEM(RDATASET => RCH_DS, NVALUE => NSUM, RATTR_VALS => RATTR_VALS);
end loop;
/* Добавим набор данных в график */
PKG_P8PANELS_VISUAL.TCHART_ADD_DATASET(RCHART => RCH, RDATASET => RCH_DS);
/* Сериализуем описание */
COUT := PKG_P8PANELS_VISUAL.TCHART_TO_XML(RCHART => RCH, NINCLUDE_DEF => 1);
end CHART_FCCOSTNOTES;
/* График по данным проектов - "Затраты на проекты" (подбор записей журнала затрат по точке графика) */
procedure CHART_FCCOSTNOTES_SELECT_COST
(
NYEAR in number, -- Год
NMONTH in number, -- Месяц
NIDENT out number -- Идентификатор буфера подобранных (списка отмеченных записей, null - не найдено)
)
is
NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса
NSELECTLIST PKG_STD.TREF; -- Рег. номер добавленной записи буфера подобранных
begin
/* Подберём записи журнала затрат */
for C in (select CN.COMPANY,
CN.RN
from FCCOSTNOTES CN
where CN.COMPANY = NCOMPANY
and TO_NUMBER(TO_CHAR(CN.COST_DATE, 'mm')) = NMONTH
and TO_NUMBER(TO_CHAR(CN.COST_DATE, 'yyyy')) = NYEAR
and exists
(select null from V_USERPRIV UP where UP.CATALOG = CN.CRN)
and CN.PROD_ORDER in (select PS.FACEACC
from PROJECTSTAGE PS
where PS.COMPANY = CN.COMPANY
and exists (select null from V_USERPRIV UP where UP.CATALOG = PS.CRN)
and exists (select null
from V_USERPRIV UP
where UP.JUR_PERS = PS.JUR_PERS
and UP.UNITCODE = 'Projects')))
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 CHART_FCCOSTNOTES_SELECT_COST;
/* Считывание записи этапа проекта */
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_SQL_BUILD.PKG_NAME(SNAME => '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_SQL_BUILD.PKG_NAME(SNAME => '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_SQL_BUILD.PKG_NAME(SNAME => '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_SQL_BUILD.PKG_NAME(SNAME => '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_SQL_BUILD.PKG_NAME(SNAME => '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;
/* Контроль актирования */
if (PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'EDCTRL_ACT') = 1) then
PKG_COND_BROKER.ADD_CLAUSE(SCLAUSE => PKG_SQL_BUILD.PKG_NAME(SNAME => 'PKG_P8PANELS_PROJECTS.STAGES_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;
/* Готовность (%, по затратам) */
if ((PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'EDCOST_READYFrom') = 1) and
(PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'EDCOST_READYTo') = 0)) then
PKG_COND_BROKER.ADD_CLAUSE(SCLAUSE => PKG_SQL_BUILD.PKG_NAME(SNAME => 'PKG_P8PANELS_PROJECTS.STAGES_GET_COST_READY') || '(RN) >= :EDCOST_READYFrom');
PKG_COND_BROKER.BIND_VARIABLE(SVARIABLE_NAME => 'EDCOST_READYFrom',
NVALUE => PKG_COND_BROKER.GET_CONDITION_NUM(SCONDITION_NAME => 'EDCOST_READYFrom'));
end if;
if ((PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'EDCOST_READYTo') = 1) and
(PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'EDCOST_READYFrom') = 0)) then
PKG_COND_BROKER.ADD_CLAUSE(SCLAUSE => PKG_SQL_BUILD.PKG_NAME(SNAME => 'PKG_P8PANELS_PROJECTS.STAGES_GET_COST_READY') || '(RN) <= :EDCOST_READYTo');
PKG_COND_BROKER.BIND_VARIABLE(SVARIABLE_NAME => 'EDCOST_READYTo',
NVALUE => PKG_COND_BROKER.GET_CONDITION_NUM(SCONDITION_NAME => 'EDCOST_READYTo'));
end if;
if ((PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'EDCOST_READYFrom') = 1) and
(PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'EDCOST_READYTo') = 1)) then
PKG_COND_BROKER.ADD_CLAUSE(SCLAUSE => PKG_SQL_BUILD.PKG_NAME(SNAME => 'PKG_P8PANELS_PROJECTS.STAGES_GET_COST_READY') || '(RN) between :EDCOST_READYFrom and :EDCOST_READYTo');
PKG_COND_BROKER.BIND_VARIABLE(SVARIABLE_NAME => 'EDCOST_READYFrom',
NVALUE => PKG_COND_BROKER.GET_CONDITION_NUM(SCONDITION_NAME => 'EDCOST_READYFrom'));
PKG_COND_BROKER.BIND_VARIABLE(SVARIABLE_NAME => 'EDCOST_READYTo',
NVALUE => PKG_COND_BROKER.GET_CONDITION_NUM(SCONDITION_NAME => 'EDCOST_READYTo'));
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 exists (select null from V_USERPRIV UP where UP.CATALOG = PS.CRN)
and exists (select null
from V_USERPRIV UP
where UP.JUR_PERS = PS.JUR_PERS
and UP.UNITCODE = 'Projects')
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))))
and exists (select /*+ INDEX(UP I_USERPRIV_CATALOG_ROLEID) */
null
from USERPRIV UP
where UP.CATALOG = PN.CRN
and UP.ROLEID in (select /*+ INDEX(UR I_USERROLES_AUTHID_FK) */
UR.ROLEID
from USERROLES UR
where UR.AUTHID = UTILIZER)
union all
select /*+ INDEX(UP I_USERPRIV_CATALOG_AUTHID) */
null
from USERPRIV UP
where UP.CATALOG = PN.CRN
and UP.AUTHID = UTILIZER)
and exists (select /*+ INDEX(UP I_USERPRIV_JUR_PERS_ROLEID) */
null
from USERPRIV UP
where UP.JUR_PERS = PN.JUR_PERS
and UP.UNITCODE = 'PayNotes'
and UP.ROLEID in (select /*+ INDEX(UR I_USERROLES_AUTHID_FK) */
UR.ROLEID
from USERROLES UR
where UR.AUTHID = UTILIZER)
union all
select /*+ INDEX(UP I_USERPRIV_JUR_PERS_AUTHID) */
null
from USERPRIV UP
where UP.JUR_PERS = PN.JUR_PERS
and UP.UNITCODE = 'PayNotes'
and UP.AUTHID = UTILIZER))
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 -- Состояние (null - не определено, 0 - без отклонений, 1 - есть отклонения)
is
NCONTR_CTRL PKG_STD.TNUMBER; -- Состояние соисполнителя этапа
NCNT_CONTR PKG_STD.TNUMBER := 0; -- Количество соисполнителей этапа
NCNT_NULL PKG_STD.TNUMBER := 0; -- Количество "безконтрольных" соисполнителей этапа
begin
/* Обходим соисполнителей этапа */
for C in (select PSPF.RN from PROJECTSTAGEPF PSPF where PSPF.PRN = NRN)
loop
/* Увеличим счётчик соисполнителей */
NCNT_CONTR := NCNT_CONTR + 1;
/* Получим состояние соисполнителя */
NCONTR_CTRL := STAGE_CONTRACTS_GET_CTRL_FIN(NPROJECTSTAGEPF => C.RN);
/* Подсчитаем количество "безконтрольных" */
if (NCONTR_CTRL is null) then
NCNT_NULL := NCNT_NULL + 1;
end if;
/* Если у соисполнителя есть отклонение - оно есть и у этапа */
if (NCONTR_CTRL = 1) then
return 1;
end if;
end loop;
/* Если ни один соисполнитель не подлежит контролю - то и состояние жтапа тоже */
if (NCNT_NULL = NCNT_CONTR) then
return null;
end if;
/* Если мы здесь - отклонений нет */
if (NCNT_CONTR > 0) then
return 0;
else
/* Нет соисполнителей и нет контроля */
return null;
end if;
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 -- Состояние (null - не определено, 0 - без отклонений, 1 - есть отклонения)
is
NCONTR_CTRL PKG_STD.TNUMBER; -- Состояние соисполнителя этапа
NCNT_CONTR PKG_STD.TNUMBER := 0; -- Количество соисполнителей этапа
NCNT_NULL PKG_STD.TNUMBER := 0; -- Количество "безконтрольных" соисполнителей этапа
begin
/* Обходим соисполнителей этапа */
for C in (select PSPF.RN from PROJECTSTAGEPF PSPF where PSPF.PRN = NRN)
loop
/* Увеличим счётчик соисполнителей */
NCNT_CONTR := NCNT_CONTR + 1;
/* Получим состояние соисполнителя */
NCONTR_CTRL := STAGE_CONTRACTS_GET_CTRL_COEXE(NPROJECTSTAGEPF => C.RN);
/* Подсчитаем количество "безконтрольных" */
if (NCONTR_CTRL is null) then
NCNT_NULL := NCNT_NULL + 1;
end if;
/* Если у соисполнителя есть отклонение - оно есть и у этапа */
if (NCONTR_CTRL = 1) then
return 1;
end if;
end loop;
/* Если ни один соисполнитель не подлежит контролю - то и состояние жтапа тоже */
if (NCNT_NULL = NCNT_CONTR) then
return null;
end if;
/* Если мы здесь - отклонений нет */
if (NCNT_CONTR > 0) then
return 0;
else
/* Нет соисполнителей и нет контроля */
return null;
end if;
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 -- Состояние (null - не определено, 0 - без отклонений, 1 - есть отклонения)
is
RPS PROJECTSTAGE%rowtype; -- Запись этапа проекта
NTRANSINVCUST PKG_STD.TREF; -- Рег. номер РНОПотр, закрывающей этап
begin
/* Читаем запись этапа */
RPS := STAGES_GET(NRN => NRN);
/* Если этап не в состоянии "Закрыт", то нечего контролировать */
if (RPS.STATE <> 2) then
return null;
end if;
/* Проверяем наличие подписанного аката */
begin
select T.RN
into NTRANSINVCUST
from TRANSINVCUST T
where T.FACEACC = RPS.FACEACCCUST
and T.STATUS = 1
and exists (select null
from TRINVCUSTCLC TC
where TC.PRN in (select TS.RN from TRANSINVCUSTSPECS TS where TS.PRN = T.RN)
and TC.FACEACCOUNT = RPS.FACEACC);
exception
when NO_DATA_FOUND then
null;
end;
/* Если мы здесь, значит этап "Закрыт", если нет закрывающего акта с заказчиком - это отклонение */
if (NTRANSINVCUST is null) then
return 1;
end if;
/* Все проверки пройдены - отклонений нет */
return 0;
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 ROUND(RSTG.ENDPLAN - sysdate);
else
return null;
end if;
end STAGES_GET_DAYS_LEFT;
/* Подбор записей журнала затрат этапа проекта */
procedure STAGES_SELECT_COST_FACT
(
NRN in number, -- Рег. номер этапа проекта
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;
/* Подбор записей расходных накладных на отпуск потребителям этапа проекта */
procedure STAGES_SELECT_SUMM_REALIZ
(
NRN in number, -- Рег. номер этапа проекта
NIDENT out number -- Идентификатор буфера подобранных (списка отмеченных записей, null - не найдено)
)
is
RSTG PROJECTSTAGE%rowtype; -- Запись этапа
NSELECTLIST PKG_STD.TREF; -- Рег. номер добавленной записи буфера подобранных
begin
/* Читаем этап */
RSTG := STAGES_GET(NRN => NRN);
/* Подберём расходные накладные на отпуск потребителям */
for C in (select T.COMPANY,
T.RN
from TRANSINVCUST T
where T.STATUS = 1
and T.COMPANY = RSTG.COMPANY
and T.FACEACC = RSTG.FACEACCCUST
and exists (select TC.RN
from TRANSINVCUSTSPECS TS,
TRINVCUSTCLC TC
where TS.PRN = T.RN
and TC.PRN = TS.RN
and TC.FACEACCOUNT = RSTG.FACEACC
and exists (select null from V_USERPRIV UP where UP.CATALOG = RSTG.CRN)
and exists (select null
from V_USERPRIV UP
where UP.JUR_PERS = RSTG.JUR_PERS
and UP.UNITCODE = 'Projects'))
and exists (select /*+ INDEX(UP I_USERPRIV_CATALOG_ROLEID) */
null
from USERPRIV UP
where UP.CATALOG = T.CRN
and UP.ROLEID in (select /*+ INDEX(UR I_USERROLES_AUTHID_FK) */
UR.ROLEID
from USERROLES UR
where UR.AUTHID = UTILIZER)
union all
select /*+ INDEX(UP I_USERPRIV_CATALOG_AUTHID) */
null
from USERPRIV UP
where UP.CATALOG = T.CRN
and UP.AUTHID = UTILIZER))
loop
/* Сформируем идентификатор буфера */
if (NIDENT is null) then
NIDENT := GEN_IDENT();
end if;
/* Добавим подобранное в список отмеченных записей */
P_SELECTLIST_BASE_INSERT(NIDENT => NIDENT,
NCOMPANY => C.COMPANY,
NDOCUMENT => C.RN,
SUNITCODE => 'GoodsTransInvoicesToConsumers',
SACTIONCODE => null,
NCRN => null,
NDOCUMENT1 => null,
SUNITCODE1 => null,
SACTIONCODE1 => null,
NRN => NSELECTLIST);
end loop;
end STAGES_SELECT_SUMM_REALIZ;
/* Получение суммы реализации этапа проекта */
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;
/* Получение % готовности этапа проекта (по затратам) */
function STAGES_GET_COST_READY
(
NRN in number -- Рег. номер этапа проекта
) return number -- % готовности
is
RSTG PROJECTSTAGE%rowtype; -- Запись этапа
NFPDARTCL_SELF_COST PKG_STD.TREF; -- Рег. номер статьи себестоимости
NCOST_FACT PKG_STD.TNUMBER; -- Сумма фактических затрат
RSELF_COST_PLAN TSTAGE_ARTS; -- Плановая себестоимость
NRES PKG_STD.TNUMBER := 0; -- Буфер для результата
begin
/* Читаем этап */
RSTG := STAGES_GET(NRN => NRN);
/* Определим рег. номер статьи калькуляции для учёта себестоимости */
FIND_FPDARTCL_CODE(NFLAG_SMART => 1,
NCOMPANY => RSTG.COMPANY,
SCODE => SFPDARTCL_SELF_COST,
NRN => NFPDARTCL_SELF_COST);
/* Опеределим сумму фактических затрат */
NCOST_FACT := STAGES_GET_COST_FACT(NRN => RSTG.RN);
/* Определим плановую себестоимость */
STAGE_ARTS_GET(NSTAGE => RSTG.RN, NFPDARTCL => NFPDARTCL_SELF_COST, RSTAGE_ARTS => RSELF_COST_PLAN);
/* Если есть и фактические затраты и найдена плановая себестоимость */
if ((NCOST_FACT > 0) and (RSELF_COST_PLAN.COUNT = 1) and (RSELF_COST_PLAN(RSELF_COST_PLAN.LAST).NPLAN <> 0)) then
/* Отношение фактических затрат к плановой себестоимость - искомый % готовности */
NRES := ROUND(NCOST_FACT / RSELF_COST_PLAN(RSELF_COST_PLAN.LAST).NPLAN * 100, 0);
/* Если затраты превысили себестоимость, то % может быть > 100, но это бессмысленно, откорректируем ситуацию */
if (NRES > 100) then
NRES := 100;
end if;
end if;
/* Вернём рассчитанное */
return NRES;
end STAGES_GET_COST_READY;
/* Список этапов */
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.TDG_FILTERS; -- Фильтры
RO PKG_P8PANELS_VISUAL.TDG_ORDERS; -- Сортировки
RDG PKG_P8PANELS_VISUAL.TDG; -- Описание таблицы
RDG_ROW PKG_P8PANELS_VISUAL.TDG_ROW; -- Строка таблицы
RCOL_VALS PKG_P8PANELS_VISUAL.TDG_COL_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.TDG_FILTERS_FROM_XML(CFILTERS => CFILTERS);
/* Читаем сортировки */
RO := PKG_P8PANELS_VISUAL.TDG_ORDERS_FROM_XML(CORDERS => CORDERS);
/* Преобразуем номер и размер страницы в номер строк с и по */
PKG_P8PANELS_VISUAL.UTL_ROWS_LIMITS_CALC(NPAGE_NUMBER => NPAGE_NUMBER,
NPAGE_SIZE => NPAGE_SIZE,
NROW_FROM => NROW_FROM,
NROW_TO => NROW_TO);
/* Инициализируем таблицу данных */
RDG := PKG_P8PANELS_VISUAL.TDG_MAKE();
/* Добавляем в таблицу описание колонок */
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NRN',
SCAPTION => 'Рег. номер',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_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.TDG_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.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SEXPECTED_RES',
SCAPTION => 'Ожидаемые результаты',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SFACEACC',
SCAPTION => 'Шифр затрат',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_COL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 0, BCLEAR => true);
PKG_P8PANELS_VISUAL.TDG_COL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 1);
PKG_P8PANELS_VISUAL.TDG_COL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 2);
PKG_P8PANELS_VISUAL.TDG_COL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 3);
PKG_P8PANELS_VISUAL.TDG_COL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 4);
PKG_P8PANELS_VISUAL.TDG_COL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 5);
PKG_P8PANELS_VISUAL.TDG_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.TDG_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.TDG_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.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NCOST_SUM',
SCAPTION => 'Стоимость',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SCURNAMES',
SCAPTION => 'Валюта',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NFIN_IN',
SCAPTION => 'Входящее финансирование',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_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.TDG_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.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NFIN_OUT',
SCAPTION => 'Исходящее финансирование',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_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.TDG_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.TDG_COL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 0, BCLEAR => true);
PKG_P8PANELS_VISUAL.TDG_COL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 1);
PKG_P8PANELS_VISUAL.TDG_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,
SHINT => '<b>Финансирование (исходящее)</b> - контроль оплаты счетов, выставленных соисполнителями по этапу.<br>' ||
'<b style="color:red">Требует внимания</b> - к этапу привязаны договоры соисполнителей, для которых не все выставленные соисполнителями счета оплачены.<br>' ||
'<b style="color:green">В норме</b> - нет договоров соисполнения с отклонениями, описанными выше.<br>' ||
'<b style="color:gray">Пусто</b> - в Системе не хватает данных для рассчёта. Убедитесь, что для этапов задана привязка к договорам с соисполнителями.');
PKG_P8PANELS_VISUAL.TDG_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,
SHINT => '<b>Контрактация</b> - контроль суммы договоров, заключеных с соисполнителями в рамках этапа.<br>' ||
'<b style="color:red">Требует внимания</b> - сумма договоров с соисполнителями, привязанных к этапу, превышает заложенные в калькуляцию плановые показатели по сответствующим статьям.<br>' ||
'<b style="color:green">В норме</b> - нет описанных выше отклонений.<br>' ||
'<b style="color:gray">Пусто</b> - в Системе не хватает данных для рассчёта. Убедитесь, что для этапа задана калькуляция и для контрагентских статей указаны плановые показатели.');
PKG_P8PANELS_VISUAL.TDG_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,
SHINT => '<b>Соисполнение</b> - контроль исполнения обязательств по договорам, заключеным с соисполнителями в рамках этапа.<br>' ||
'<b style="color:red">Требует внимания</b> - до окончания этапа осталось менее ' ||
TO_CHAR(NDAYS_LEFT_LIMIT) ||
' дней, при этом зафиксирован положительный остаток к поставке/актированию по привязанным к нему договорам соисполнителей.<br>' ||
'<b style="color:green">В норме</b> - нет описанных выше отклонений.<br>' ||
'<b style="color:gray">Пусто</b> - в Системе не хватает данных для рассчёта. Убедитесь, что для этапа задана привязка к договорам с соисполнителями и плановый срок окончания.');
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NDAYS_LEFT',
SCAPTION => 'Дней до окончания',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_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,
SHINT => '<b>Сроки</b> - контроль сроков исполнения работ по этапу.<br>' ||
'<b style="color:red">Требует внимания</b> - до окончания этапа осталось менее ' ||
TO_CHAR(NDAYS_LEFT_LIMIT) || ' дней.<br>' ||
'<b style="color:green">В норме</b> - нет описанных выше отклонений.<br>' ||
'<b style="color:gray">Пусто</b> - в Системе не хватает данных для рассчёта. Убедитесь, что для этапа задан плановый срок окончания.');
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NCOST_FACT',
SCAPTION => 'Сумма фактических затрат',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_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.TDG_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.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NSUMM_REALIZ',
SCAPTION => 'Сумма реализации',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SLNK_UNIT_NSUMM_REALIZ',
SCAPTION => 'Сумма реализации (код раздела ссылки)',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NLNK_DOCUMENT_NSUMM_REALIZ',
SCAPTION => 'Сумма реализации (документ ссылки)',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NSUMM_INCOME',
SCAPTION => 'Сумма прибыли',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NINCOME_PRC',
SCAPTION => 'Процент прибыли',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_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,
SHINT => '<b>Затраты</b> - контроль затрат, понесённых в ходе выполнения работ по этапу.<br>' ||
'<b style="color:red">Требует внимания</b> - сумма фактических затрат этапа по некоторым статьям калькуляции превысила плановую.<br>' ||
'<b style="color:green">В норме</b> - нет описанных выше отклонений.<br>' ||
'<b style="color:gray">Пусто</b> - в Системе не хватает данных для рассчёта. Убедитесь, что для этапа задана действующая калькуляция с указанием плановых значений по статьям, подлежащим контролю.');
PKG_P8PANELS_VISUAL.TDG_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,
SHINT => '<b>Актирование</b> - контроль актирования работ, выполненных по этапу, со стороны заказчика.<br>' ||
'<b style="color:red">Требует внимания</b> - этап в состоянии "Закрыт", но при этом в Системе отсутствует утверждённая "Расходная накладная на отпуск потребителю" для данного этапа.<br>' ||
'<b style="color:green">В норме</b> - нет описанных выше отклонений.<br>' ||
'<b style="color:gray">Пусто</b> - в Системе не хватает данных для рассчёта. Убедитесь, что этап, если работы по нему завершены, переведен в состояние "Закрыт".');
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NCOST_READY',
SCAPTION => 'Готов (%, затраты)',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
SCOND_FROM => 'EDCOST_READYFrom',
SCOND_TO => 'EDCOST_READYTo',
BORDER => true,
BFILTER => true);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NPROJECT',
SCAPTION => 'Рег. номер проекта',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
/* Обходим данные */
begin
/* Добавляем подсказку совместимости */
CSQL := PKG_SQL_BUILD.COMPATIBLE(SSQL => CSQL);
/* Формируем запрос */
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => 'select *');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from (select D.*,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.SQLROWNUM() || ' NROW');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from (select PS.RN NRN,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' PS.NUMB SNUMB,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' PS."NAME" SNAME,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' PS.EXPECTED_RES SEXPECTED_RES,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' FAC.NUMB SFACEACC,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' PS."STATE" NSTATE,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' PS.BEGPLAN DBEGPLAN,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' PS.ENDPLAN DENDPLAN,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' PS.COST_SUM_BASECURR NCOST_SUM,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' CN.INTCODE SCURNAMES,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.PKG_NAME(SNAME => 'PKG_P8PANELS_PROJECTS.STAGES_GET_FIN_IN') || '(PS.RN) NFIN_IN,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.WRAP_STR(SVALUE => 'Paynotes') || ' SLNK_UNIT_NFIN_IN,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.WRAP_NUM(NVALUE => 0) || ' NLNK_DOCUMENT_NFIN_IN,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.PKG_NAME(SNAME => 'PKG_P8PANELS_PROJECTS.STAGES_GET_FIN_OUT') || '(PS.RN) NFIN_OUT,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.WRAP_STR(SVALUE => 'Paynotes') || ' SLNK_UNIT_NFIN_OUT,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.WRAP_NUM(NVALUE => 1) || ' NLNK_DOCUMENT_NFIN_OUT,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.PKG_NAME(SNAME => 'PKG_P8PANELS_PROJECTS.STAGES_GET_CTRL_FIN') || '(PS.RN) NCTRL_FIN,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.PKG_NAME(SNAME => 'PKG_P8PANELS_PROJECTS.STAGES_GET_CTRL_CONTR') || '(PS.RN) NCTRL_CONTR,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.PKG_NAME(SNAME => 'PKG_P8PANELS_PROJECTS.STAGES_GET_CTRL_COEXEC') || '(PS.RN) NCTRL_COEXEC,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.PKG_NAME(SNAME => 'PKG_P8PANELS_PROJECTS.STAGES_GET_DAYS_LEFT') || '(PS.RN) NDAYS_LEFT,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.PKG_NAME(SNAME => 'PKG_P8PANELS_PROJECTS.STAGES_GET_CTRL_PERIOD') || '(PS.RN) NCTRL_PERIOD,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.PKG_NAME(SNAME => 'PKG_P8PANELS_PROJECTS.STAGES_GET_COST_FACT') || '(PS.RN) NCOST_FACT,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.WRAP_STR(SVALUE => 'CostNotes') || ' SLNK_UNIT_NCOST_FACT,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.WRAP_NUM(NVALUE => 1) || ' NLNK_DOCUMENT_NCOST_FACT,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.PKG_NAME(SNAME => 'PKG_P8PANELS_PROJECTS.STAGES_GET_SUMM_REALIZ') || '(PS.RN, :NFPDARTCL_REALIZ) NSUMM_REALIZ,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.WRAP_STR(SVALUE => 'GoodsTransInvoicesToConsumers') || ' SLNK_UNIT_NSUMM_REALIZ,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.WRAP_NUM(NVALUE => 1) || ' NLNK_DOCUMENT_NSUMM_REALIZ,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.PKG_NAME(SNAME => 'PKG_P8PANELS_PROJECTS.STAGES_GET_CTRL_COST') || '(PS.RN) NCTRL_COST,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.PKG_NAME(SNAME => 'PKG_P8PANELS_PROJECTS.STAGES_GET_CTRL_ACT') || '(PS.RN) NCTRL_ACT,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.PKG_NAME(SNAME => 'PKG_P8PANELS_PROJECTS.STAGES_GET_COST_READY') || '(PS.RN) NCOST_READY,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' PS.PRN NPROJECT');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from PROJECTSTAGE PS');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' left outer join FACEACC FAC on PS.FACEACC = FAC.RN,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' PROJECT P,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' CURNAMES CN');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' where PS.PRN = P.RN');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and P.CURNAMES = CN.RN');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and exists (select null from V_USERPRIV UP where UP."CATALOG" = PS.CRN)');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and exists (select null from V_USERPRIV UP where UP.JUR_PERS = PS.JUR_PERS and UP.UNITCODE = ' || PKG_SQL_BUILD.WRAP_STR(SVALUE => 'Projects') || ')');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and PS.RN in (select ID from COND_BROKER_IDSMART where IDENT = :NIDENT) %ORDER_BY%) D) F');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' where F.NROW between :NROW_FROM and :NROW_TO');
/* Учтём сортировки */
PKG_P8PANELS_VISUAL.TDG_ORDERS_SET_QUERY(RDATA_GRID => RDG,
RORDERS => RO,
SPATTERN => '%ORDER_BY%',
CSQL => CSQL);
/* Учтём фильтры */
PKG_P8PANELS_VISUAL.TDG_FILTERS_SET_QUERY(NIDENT => NIDENT,
NCOMPANY => NCOMPANY,
NPARENT => NPRN,
SUNIT => 'ProjectsStages',
SPROCEDURE => PKG_SQL_BUILD.PKG_NAME(SNAME => '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_STR(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);
PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 32);
/* Делаем выборку */
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.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NRN',
ICURSOR => ICURSOR,
NPOSITION => 1,
BCLEAR => true);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SNUMB', ICURSOR => ICURSOR, NPOSITION => 2);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SNAME', ICURSOR => ICURSOR, NPOSITION => 3);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SEXPECTED_RES',
ICURSOR => ICURSOR,
NPOSITION => 4);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SFACEACC',
ICURSOR => ICURSOR,
NPOSITION => 5);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NSTATE',
ICURSOR => ICURSOR,
NPOSITION => 6);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLD(RROW => RDG_ROW,
SNAME => 'DBEGPLAN',
ICURSOR => ICURSOR,
NPOSITION => 7);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLD(RROW => RDG_ROW,
SNAME => 'DENDPLAN',
ICURSOR => ICURSOR,
NPOSITION => 8);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NCOST_SUM',
ICURSOR => ICURSOR,
NPOSITION => 9);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SCURNAMES',
ICURSOR => ICURSOR,
NPOSITION => 10);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NFIN_IN',
ICURSOR => ICURSOR,
NPOSITION => 11);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SLNK_UNIT_NFIN_IN',
ICURSOR => ICURSOR,
NPOSITION => 12);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NLNK_DOCUMENT_NFIN_IN',
ICURSOR => ICURSOR,
NPOSITION => 13);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NFIN_OUT',
ICURSOR => ICURSOR,
NPOSITION => 14);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SLNK_UNIT_NFIN_OUT',
ICURSOR => ICURSOR,
NPOSITION => 15);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NLNK_DOCUMENT_NFIN_OUT',
ICURSOR => ICURSOR,
NPOSITION => 16);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NCTRL_FIN',
ICURSOR => ICURSOR,
NPOSITION => 17);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NCTRL_CONTR',
ICURSOR => ICURSOR,
NPOSITION => 18);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NCTRL_COEXEC',
ICURSOR => ICURSOR,
NPOSITION => 19);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NDAYS_LEFT',
ICURSOR => ICURSOR,
NPOSITION => 20);
PKG_P8PANELS_VISUAL.TDG_ROW_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.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NCOST_FACT', NVALUE => NCOST_FACT);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SLNK_UNIT_NCOST_FACT',
ICURSOR => ICURSOR,
NPOSITION => 23);
PKG_P8PANELS_VISUAL.TDG_ROW_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.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NSUMM_REALIZ', NVALUE => NSUMM_REALIZ);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SLNK_UNIT_NSUMM_REALIZ',
ICURSOR => ICURSOR,
NPOSITION => 26);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NLNK_DOCUMENT_NSUMM_REALIZ',
ICURSOR => ICURSOR,
NPOSITION => 27);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NSUMM_INCOME', NVALUE => NSUMM_INCOME);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NINCOME_PRC', NVALUE => NINCOME_PRC);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NCTRL_COST',
ICURSOR => ICURSOR,
NPOSITION => 28);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NCTRL_ACT',
ICURSOR => ICURSOR,
NPOSITION => 29);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NCOST_READY',
ICURSOR => ICURSOR,
NPOSITION => 30);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NPROJECT',
ICURSOR => ICURSOR,
NPOSITION => 31);
/* Добавляем строку в таблицу */
PKG_P8PANELS_VISUAL.TDG_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
end loop;
/* Освобождаем курсор */
PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR);
exception
when others then
PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR);
raise;
end;
/* Сериализуем описание */
COUT := PKG_P8PANELS_VISUAL.TDG_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => NINCLUDE_DEF);
end STAGES_LIST;
/* Подбор записей журнала затрат по статье калькуляции этапа проекта */
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)))
and exists (select null from V_USERPRIV UP where UP.CATALOG = PS.CRN)
and exists (select null from V_USERPRIV UP where UP.JUR_PERS = PS.JUR_PERS and UP.UNITCODE = 'Projects')
and exists (select null from V_USERPRIV UP where UP.CATALOG = CN.CRN))
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)))
and exists (select null from V_USERPRIV UP where UP.CATALOG = EPF.CRN)
and exists (select null from V_USERPRIV UP where UP.JUR_PERS = EPF.JUR_PERS and UP.UNITCODE = 'Projects')
and exists (select null from V_USERPRIV UP where UP.CATALOG = S.CRN)
and exists (select null from V_USERPRIV UP where UP.JUR_PERS = S.JUR_PERS and UP.UNITCODE = 'Contracts'))
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
RSTG := STAGES_GET(NRN => NSTAGE);
exception
when others then
null;
end;
/* Если считано успешно - будем искать данные */
if (RSTG.RN is not null) then
/* Определим рег. номер доп. свойства для налоговой группы проекта */
FIND_DOCS_PROPS_CODE(NFLAG_SMART => 1,
NCOMPANY => RSTG.COMPANY,
SCODE => SDP_STAX_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, -- Рег. номер этапа проекта
NFPDARTCL in number := null, -- Рег. номер статьи затрат (null - брать все)
NINC_COST in number := 0, -- Включить сведения о затратах (0 - нет, 1 - да)
NINC_CONTR in number := 0, -- Включить сведения о контрактации (0 - нет, 1 - да)
RSTAGE_ARTS out TSTAGE_ARTS -- Список статей этапа проекта
)
is
RSTG PROJECTSTAGE%rowtype; -- Запись этапа проекта
NCTL_COST_DP PKG_STD.TREF; -- Рег. номер доп. свойства, определяющего необходимость контроля затрат по статье
NCTL_CONTR_DP PKG_STD.TREF; -- Рег. номер доп. свойства, определяющего необходимость контроля контрактации по статье
I PKG_STD.TNUMBER; -- Счётчик статей в результирующей коллекции
begin
/* Читаем этап */
RSTG := STAGES_GET(NRN => NSTAGE);
/* Определим дополнительные свойства - контроль затрат */
if (NINC_COST = 1) then
FIND_DOCS_PROPS_CODE(NFLAG_SMART => 1, NCOMPANY => RSTG.COMPANY, SCODE => SDP_SCTL_COST, NRN => NCTL_COST_DP);
end if;
/* Определим дополнительные свойства - контроль контрактации */
if (NINC_CONTR = 1) then
FIND_DOCS_PROPS_CODE(NFLAG_SMART => 1, NCOMPANY => RSTG.COMPANY, SCODE => SDP_SCTL_CONTR, NRN => NCTL_CONTR_DP);
end if;
/* Инициализируем коллекцию */
RSTAGE_ARTS := TSTAGE_ARTS();
/* Подбираем активную структуру цены этапа проекта и её обходим статьи */
for C in (select CSPA.NUMB SNUMB,
A.RN NARTICLE,
A.NAME SARTICLE,
CSPA.COST_SUM NCOST_SUM
from PROJECTSTAGE PS,
STAGES CS,
CONTRPRSTRUCT CSP,
CONTRPRCLC CSPA,
FPDARTCL A
where PS.RN = RSTG.RN
and PS.FACEACCCUST = CS.FACEACC
and CSP.PRN = CS.RN
and CSP.SIGN_ACT = 1
and CSPA.PRN = CSP.RN
and CSPA.COST_ARTICLE = A.RN
and ((NFPDARTCL is null) or ((NFPDARTCL is not null) and (A.RN = NFPDARTCL)))
and exists (select null from V_USERPRIV UP where UP.CATALOG = PS.CRN)
and exists (select null from V_USERPRIV UP where UP.JUR_PERS = PS.JUR_PERS and UP.UNITCODE = 'Projects')
and exists (select null from V_USERPRIV UP where UP.CATALOG = CS.CRN)
and exists (select null from V_USERPRIV UP where UP.JUR_PERS = CS.JUR_PERS and UP.UNITCODE = 'Contracts')
order by CSPA.NUMB)
loop
/* Добавим строку в коллекцию */
RSTAGE_ARTS.EXTEND();
I := RSTAGE_ARTS.LAST;
/* Наполним её значениями из хранилища */
RSTAGE_ARTS(I).NRN := C.NARTICLE;
RSTAGE_ARTS(I).SCODE := C.SNUMB;
RSTAGE_ARTS(I).SNAME := C.SARTICLE;
RSTAGE_ARTS(I).NPLAN := C.NCOST_SUM;
/* Если просили включить сведения о затратах и статья поддерживает это */
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;
end loop;
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.TDG_FILTERS; -- Фильтры
RF_CTRL_COST PKG_P8PANELS_VISUAL.TDG_FILTER; -- Фильтр по колонке "Контроль (затраты)"
NCTRL_COST_FROM PKG_STD.TNUMBER; -- Нижняя граница диапазона фильтра по колонке "Контроль (затраты)"
NCTRL_COST_TO PKG_STD.TNUMBER; -- Верхняя граница диапазона фильтра по колонке "Контроль (затраты)"
RF_CTRL_CONTR PKG_P8PANELS_VISUAL.TDG_FILTER; -- Фильтр по колонке "Контроль (контрактация)"
NCTRL_CONTR_FROM PKG_STD.TNUMBER; -- Нижняя граница диапазона фильтра по колонке "Контроль (контрактация)"
NCTRL_CONTR_TO PKG_STD.TNUMBER; -- Верхняя граница диапазона фильтра по колонке "Контроль (контрактация)"
RDG PKG_P8PANELS_VISUAL.TDG; -- Описание таблицы
RDG_ROW PKG_P8PANELS_VISUAL.TDG_ROW; -- Строка таблицы
RCOL_VALS PKG_P8PANELS_VISUAL.TDG_COL_VALS; -- Предопределённые значения столбцов
RSTAGE_ARTS TSTAGE_ARTS; -- Список статей этапа проекта
begin
/* Читаем фильтры */
RF := PKG_P8PANELS_VISUAL.TDG_FILTERS_FROM_XML(CFILTERS => CFILTERS);
/* Найдем фильтр по контролю затрат */
RF_CTRL_COST := PKG_P8PANELS_VISUAL.TDG_FILTERS_FIND(RFILTERS => RF, SNAME => 'NCTRL_COST');
PKG_P8PANELS_VISUAL.TDG_FILTER_TO_NUMBER(RFILTER => RF_CTRL_COST, NFROM => NCTRL_COST_FROM, NTO => NCTRL_COST_TO);
/* Найдем фильтр по контролю контрактации */
RF_CTRL_CONTR := PKG_P8PANELS_VISUAL.TDG_FILTERS_FIND(RFILTERS => RF, SNAME => 'NCTRL_CONTR');
PKG_P8PANELS_VISUAL.TDG_FILTER_TO_NUMBER(RFILTER => RF_CTRL_CONTR,
NFROM => NCTRL_CONTR_FROM,
NTO => NCTRL_CONTR_TO);
/* Инициализируем таблицу данных */
RDG := PKG_P8PANELS_VISUAL.TDG_MAKE();
/* Добавляем в таблицу описание колонок */
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NRN',
SCAPTION => 'Рег. номер',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SNUMB',
SCAPTION => 'Номер',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SNAME',
SCAPTION => 'Наименование статьи',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NPLAN',
SCAPTION => 'План',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NCOST_FACT',
SCAPTION => 'Фактические затраты',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NCOST_DIFF',
SCAPTION => 'Отклонение по затратам',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_COL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 0, BCLEAR => true);
PKG_P8PANELS_VISUAL.TDG_COL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 1);
PKG_P8PANELS_VISUAL.TDG_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.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NCONTR',
SCAPTION => 'Законтрактовано',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NCONTR_LEFT',
SCAPTION => 'Осталось законтрактовать',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_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.TDG_ROW_ADD_COL(RROW => RDG_ROW,
SNAME => 'NRN',
NVALUE => RSTAGE_ARTS(I).NRN,
BCLEAR => true);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SNUMB', SVALUE => RSTAGE_ARTS(I).SCODE);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SNAME', SVALUE => RSTAGE_ARTS(I).SNAME);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NPLAN', NVALUE => RSTAGE_ARTS(I).NPLAN);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW,
SNAME => 'NCOST_FACT',
NVALUE => RSTAGE_ARTS(I).NCOST_FACT);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW,
SNAME => 'NCOST_DIFF',
NVALUE => RSTAGE_ARTS(I).NCOST_DIFF);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW,
SNAME => 'NCTRL_COST',
NVALUE => RSTAGE_ARTS(I).NCTRL_COST);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NCONTR', NVALUE => RSTAGE_ARTS(I).NCONTR);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW,
SNAME => 'NCONTR_LEFT',
NVALUE => RSTAGE_ARTS(I).NCONTR_LEFT);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW,
SNAME => 'NCTRL_CONTR',
NVALUE => RSTAGE_ARTS(I).NCTRL_CONTR);
/* Добавляем строку в таблицу */
PKG_P8PANELS_VISUAL.TDG_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
end if;
end loop;
end if;
/* Сериализуем описание */
COUT := PKG_P8PANELS_VISUAL.TDG_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => NINCLUDE_DEF);
end STAGE_ARTS_LIST;
/* Считывание записи соисполнителя этапа проекта */
function STAGE_CONTRACTS_GET_PSPF
(
NPROJECTSTAGEPF in number -- Рег. номер соисполнителя этапа проекта
) return PROJECTSTAGEPF%rowtype -- Запись соисполнителя этапа проекта
is
RRES PROJECTSTAGEPF%rowtype; -- Буфер для результата
begin
select PS.* into RRES from PROJECTSTAGEPF PS where PS.RN = NPROJECTSTAGEPF;
return RRES;
exception
when NO_DATA_FOUND then
PKG_MSG.RECORD_NOT_FOUND(NFLAG_SMART => 0, NDOCUMENT => NPROJECTSTAGEPF, SUNIT_TABLE => 'PROJECTSTAGEPF');
end STAGE_CONTRACTS_GET_PSPF;
/* Список договоров этапа проекта */
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');
/* Контроль финансирования */
if (PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'EDCTRL_FIN') = 1) then
PKG_COND_BROKER.ADD_CLAUSE(SCLAUSE => PKG_SQL_BUILD.PKG_NAME(SNAME => 'PKG_P8PANELS_PROJECTS.STAGE_CONTRACTS_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_COEXEC') = 1) then
PKG_COND_BROKER.ADD_CLAUSE(SCLAUSE => PKG_SQL_BUILD.PKG_NAME(SNAME => 'PKG_P8PANELS_PROJECTS.STAGE_CONTRACTS_GET_CTRL_COEXE') || '(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;
end STAGE_CONTRACTS_COND;
/* Подбор входящих счетов на оплату соисполнителя этапа проекта */
procedure STAGE_CONTRACTS_SELECT_PAY_IN
(
NPROJECTSTAGEPF in number, -- Рег. номер соисполнителя этапа проекта
NIDENT out number -- Идентификатор буфера подобранных (списка отмеченных записей, null - не найдено)
)
is
NSELECTLIST PKG_STD.TREF; -- Рег. номер добавленной записи буфера подобранных
begin
/* Подберём счета */
for C in (select PAI.COMPANY,
PAI.RN
from PROJECTSTAGEPF PSPF,
PROJECTSTAGE PS,
PAYACCIN PAI
where PSPF.RN = NPROJECTSTAGEPF
and PSPF.PRN = PS.RN
and PSPF.FACEACC = PAI.FACEACC
and PAI.DOC_STATE = 1
and exists (select null
from PAYACCINSPCLC PCLC
where PCLC.PRN in (select PAIS.RN from PAYACCINSPEC PAIS where PAIS.PRN = PAI.RN)
and PCLC.FACEACCOUNT = PS.FACEACC)
and exists (select null from V_USERPRIV UP where UP.CATALOG = PSPF.CRN)
and exists (select null
from V_USERPRIV UP
where UP.JUR_PERS = PSPF.JUR_PERS
and UP.UNITCODE = 'Projects')
and exists (select null from V_USERPRIV UP where UP.CATALOG = PAI.CRN))
loop
/* Сформируем идентификатор буфера */
if (NIDENT is null) then
NIDENT := GEN_IDENT();
end if;
/* Добавим подобранное в список отмеченных записей */
P_SELECTLIST_BASE_INSERT(NIDENT => NIDENT,
NCOMPANY => C.COMPANY,
NDOCUMENT => C.RN,
SUNITCODE => 'PaymentAccountsIn',
SACTIONCODE => null,
NCRN => null,
NDOCUMENT1 => null,
SUNITCODE1 => null,
SACTIONCODE1 => null,
NRN => NSELECTLIST);
end loop;
end STAGE_CONTRACTS_SELECT_PAY_IN;
/* Подбор приходных накладных соисполнителя этапа проекта */
procedure STAGE_CONTRACTS_SELECT_ININV
(
NPROJECTSTAGEPF in number, -- Рег. номер соисполнителя этапа проекта
NIDENT out number -- Идентификатор буфера подобранных (списка отмеченных записей, null - не найдено)
)
is
NSELECTLIST PKG_STD.TREF; -- Рег. номер добавленной записи буфера подобранных
begin
/* Подберём счета */
for C in (select I.COMPANY,
I.RN
from PROJECTSTAGEPF PSPF,
PROJECTSTAGE PS,
ININVOICES I
where PSPF.RN = NPROJECTSTAGEPF
and PSPF.PRN = PS.RN
and PSPF.FACEACC = I.FACEACC
and I.STATUS = 2
and exists (select null
from ININVOICESSPC ICLC
where ICLC.PRN in (select ISP.RN from ININVOICESSPECS ISP where ISP.PRN = I.RN)
and ICLC.FACEACCOUNT = PS.FACEACC)
and exists (select null from V_USERPRIV UP where UP.CATALOG = PSPF.CRN)
and exists (select null
from V_USERPRIV UP
where UP.JUR_PERS = PSPF.JUR_PERS
and UP.UNITCODE = 'Projects')
and exists (select /*+ INDEX(UP I_USERPRIV_CATALOG_ROLEID) */
null
from USERPRIV UP
where UP.CATALOG = I.CRN
and UP.ROLEID in (select /*+ INDEX(UR I_USERROLES_AUTHID_FK) */
UR.ROLEID
from USERROLES UR
where UR.AUTHID = UTILIZER)
union all
select /*+ INDEX(UP I_USERPRIV_CATALOG_AUTHID) */
null
from USERPRIV UP
where UP.CATALOG = I.CRN
and UP.AUTHID = UTILIZER))
loop
/* Сформируем идентификатор буфера */
if (NIDENT is null) then
NIDENT := GEN_IDENT();
end if;
/* Добавим подобранное в список отмеченных записей */
P_SELECTLIST_BASE_INSERT(NIDENT => NIDENT,
NCOMPANY => C.COMPANY,
NDOCUMENT => C.RN,
SUNITCODE => 'IncomingInvoices',
SACTIONCODE => null,
NCRN => null,
NDOCUMENT1 => null,
SUNITCODE1 => null,
SACTIONCODE1 => null,
NRN => NSELECTLIST);
end loop;
end STAGE_CONTRACTS_SELECT_ININV;
/* Подбор платежей финансирования соисполнителя этапа проекта */
procedure STAGE_CONTRACTS_SELECT_FIN_OUT
(
NPROJECTSTAGEPF in number, -- Рег. номер соисполнителя этапа проекта
NIDENT out number -- Идентификатор буфера подобранных (списка отмеченных записей, null - не найдено)
)
is
NSELECTLIST PKG_STD.TREF; -- Рег. номер добавленной записи буфера подобранных
begin
/* Подберём платежи */
for C in (select PN.COMPANY,
PN.RN
from PROJECTSTAGEPF PSPF,
PROJECTSTAGE PS,
PAYNOTES PN
where PSPF.RN = NPROJECTSTAGEPF
and PSPF.PRN = PS.RN
and PSPF.FACEACC = PN.FACEACC
and PN.SIGNPLAN = 0
and exists (select null
from PAYNOTESCLC PNCLC
where PNCLC.PRN = PN.RN
and PNCLC.FACEACCOUNT = PS.FACEACC)
and exists (select null from V_USERPRIV UP where UP.CATALOG = PSPF.CRN)
and exists (select null
from V_USERPRIV UP
where UP.JUR_PERS = PSPF.JUR_PERS
and UP.UNITCODE = 'Projects')
and exists (select /*+ INDEX(UP I_USERPRIV_CATALOG_ROLEID) */
null
from USERPRIV UP
where UP.CATALOG = PN.CRN
and UP.ROLEID in (select /*+ INDEX(UR I_USERROLES_AUTHID_FK) */
UR.ROLEID
from USERROLES UR
where UR.AUTHID = UTILIZER)
union all
select /*+ INDEX(UP I_USERPRIV_CATALOG_AUTHID) */
null
from USERPRIV UP
where UP.CATALOG = PN.CRN
and UP.AUTHID = UTILIZER)
and exists (select /*+ INDEX(UP I_USERPRIV_JUR_PERS_ROLEID) */
null
from USERPRIV UP
where UP.JUR_PERS = PN.JUR_PERS
and UP.UNITCODE = 'PayNotes'
and UP.ROLEID in (select /*+ INDEX(UR I_USERROLES_AUTHID_FK) */
UR.ROLEID
from USERROLES UR
where UR.AUTHID = UTILIZER)
union all
select /*+ INDEX(UP I_USERPRIV_JUR_PERS_AUTHID) */
null
from USERPRIV UP
where UP.JUR_PERS = PN.JUR_PERS
and UP.UNITCODE = 'PayNotes'
and UP.AUTHID = UTILIZER))
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 STAGE_CONTRACTS_SELECT_FIN_OUT;
/* Получение состояния финансирования по договору соисполнителя этапа проекта */
function STAGE_CONTRACTS_GET_CTRL_FIN
(
NPROJECTSTAGEPF in number -- Рег. номер соисполнителя этапа проекта
) return number -- Состояние (null - не определено, 0 - без отклонений, 1 - есть отклонения)
is
NTMP PKG_STD.TNUMBER; -- Буфер для вызова процедуры расчёта
NCTRL_FIN PKG_STD.TNUMBER; -- Буфер для результата
begin
/* Получим сведения по договору соисполнителя этапа */
STAGE_CONTRACTS_GET(NPROJECTSTAGEPF => NPROJECTSTAGEPF,
NINC_FIN => 1,
NINC_COEXEC => 0,
NPAY_IN => NTMP,
NFIN_OUT => NTMP,
NPAY_IN_REST => NTMP,
NFIN_REST => NTMP,
NCTRL_FIN => NCTRL_FIN,
NCOEXEC_IN => NTMP,
NCOEXEC_REST => NTMP,
NCTRL_COEXEC => NTMP);
/* Вернём результат */
return NCTRL_FIN;
end STAGE_CONTRACTS_GET_CTRL_FIN;
/* Получение состояния соисполнения по договору соисполнителя этапа проекта */
function STAGE_CONTRACTS_GET_CTRL_COEXE
(
NPROJECTSTAGEPF in number -- Рег. номер соисполнителя этапа проекта
) return number -- Состояние (null - не определено, 0 - без отклонений, 1 - есть отклонения)
is
NTMP PKG_STD.TNUMBER; -- Буфер для вызова процедуры расчёта
NCTRL_COEXEC PKG_STD.TNUMBER; -- Буфер для результата
begin
/* Получим сведения по договору соисполнителя этапа */
STAGE_CONTRACTS_GET(NPROJECTSTAGEPF => NPROJECTSTAGEPF,
NINC_FIN => 0,
NINC_COEXEC => 1,
NPAY_IN => NTMP,
NFIN_OUT => NTMP,
NPAY_IN_REST => NTMP,
NFIN_REST => NTMP,
NCTRL_FIN => NTMP,
NCOEXEC_IN => NTMP,
NCOEXEC_REST => NTMP,
NCTRL_COEXEC => NCTRL_COEXEC);
/* Вернём результат */
return NCTRL_COEXEC;
end STAGE_CONTRACTS_GET_CTRL_COEXE;
/* Получение сведений по договору соисполнителя этапа проекта */
procedure STAGE_CONTRACTS_GET
(
NPROJECTSTAGEPF in number, -- Рег. номер соисполнителя этапа проекта
NINC_FIN in number := 0, -- Включить сведения о финансировании (0 - нет, 1 - да)
NINC_COEXEC in number := 0, -- Включить сведения о соисполнении (0 - нет, 1 - да)
NPAY_IN out number, -- Сведения о финансировании - сумма акцептованных счетов на оплату
NFIN_OUT out number, -- Сведения о финансировании - сумма оплаченных счетов на оплату
NPAY_IN_REST out number, -- Сведения о финансировании - сумма оставшихся к оплате счетов на оплату
NFIN_REST out number, -- Сведения о финансировании - общий остаток к оплате по договору
NCTRL_FIN out number, -- Сведения о финансировании - состояние (null - не определено, 0 - без отклонений, 1 - есть отклонения)
NCOEXEC_IN out number, -- Сведения о соисполнении - получено актов/накладных
NCOEXEC_REST out number, -- Сведения о соисполнении - остаток к актированию/поставке
NCTRL_COEXEC out number -- Сведения о соисполнении - состояние (null - не определено, 0 - без отклонений, 1 - есть отклонения)
)
is
RPSPF PROJECTSTAGEPF%rowtype; -- Запись соисполнителя этапа проекта
RPS PROJECTSTAGE%rowtype; -- Запись родительского этапа проекта
NDAYS_LEFT PKG_STD.TNUMBER; -- Остаток дней до завершения родительского этапа проекта
begin
/* Читаем запись соисполнителя этапа проекта */
RPSPF := STAGE_CONTRACTS_GET_PSPF(NPROJECTSTAGEPF => NPROJECTSTAGEPF);
/* Читаем записб родительского этапа проекта */
RPS := STAGES_GET(NRN => RPSPF.PRN);
/* Инициализируем выходные значения */
NPAY_IN := 0;
NFIN_OUT := 0;
NPAY_IN_REST := 0;
NFIN_REST := RPSPF.COST_PLAN;
NCTRL_FIN := null;
NCOEXEC_IN := 0;
NCOEXEC_REST := RPSPF.COST_PLAN;
NCTRL_COEXEC := null;
/* Если ЛС этапа проекта задан */
if (RPS.FACEACC is not null) then
/* Если нужны сведения о финансировании */
if (NINC_FIN = 1) then
/* Сумма акцептованных счетов на оплату - по ВСО с ЛС соисполнителя этапа проекта, в калькуляции которых присутствует ЛС затрат этапа проекта */
select sum(PAI.SUMMWITHNDS * PAI.FA_BASECOURS)
into NPAY_IN
from PAYACCIN PAI
where PAI.FACEACC = RPSPF.FACEACC
and PAI.DOC_STATE = 1
and exists (select null
from PAYACCINSPCLC PCLC
where PCLC.PRN in (select PAIS.RN from PAYACCINSPEC PAIS where PAIS.PRN = PAI.RN)
and PCLC.FACEACCOUNT = RPS.FACEACC);
/* Сумма оплаченных счетов на оплату - по расходным факт. ЖП с ЛС соисполнителя этапа проекта, в калькуляции которых присутствует ЛС затрат этапа проекта */
select sum(PN.PAY_SUM * (PN.CURR_RATE_BASE / PN.CURR_RATE))
into NFIN_OUT
from PAYNOTES PN
where PN.FACEACC = RPSPF.FACEACC
and PN.SIGNPLAN = 0
and exists (select null
from PAYNOTESCLC PNCLC
where PNCLC.PRN = PN.RN
and PNCLC.FACEACCOUNT = RPS.FACEACC);
/* Сумма оставшихся к оплате счетов на оплату */
NPAY_IN_REST := COALESCE(NPAY_IN, 0) - COALESCE(NFIN_OUT, 0);
/* Общий остаток к оплате по договору */
NFIN_REST := RPSPF.COST_PLAN - COALESCE(NFIN_OUT, 0);
/* Контроль отклонений по финансированию (состояние) */
if (NPAY_IN is null) then
NCTRL_FIN := null;
else
if (NPAY_IN_REST > 0) then
NCTRL_FIN := 1;
else
NCTRL_FIN := 0;
end if;
end if;
/* Приведение значений */
NPAY_IN := COALESCE(NPAY_IN, 0);
NFIN_OUT := COALESCE(NFIN_OUT, 0);
end if;
/* Если нужны сведения о соисполнении */
if (NINC_COEXEC = 1) then
/* Получено актов/накладных - по отработанным как факт ПН с ЛС соисполнителя этапа проекта, в калькуляции которых присутствует ЛС затрат этапа проекта */
select sum(I.SUMMTAX * (I.CURBASECOURS / I.CURCOURS))
into NCOEXEC_IN
from ININVOICES I
where I.FACEACC = RPSPF.FACEACC
and I.STATUS = 2
and exists (select null
from ININVOICESSPC ICLC
where ICLC.PRN in (select ISP.RN from ININVOICESSPECS ISP where ISP.PRN = I.RN)
and ICLC.FACEACCOUNT = RPS.FACEACC);
/* Общий остаток к актированию/поставке */
NCOEXEC_REST := RPSPF.COST_PLAN - COALESCE(NCOEXEC_IN, 0);
/* Контроль отклонений по соисполнению (состояние) */
NDAYS_LEFT := STAGES_GET_DAYS_LEFT(NRN => RPS.RN);
if (NDAYS_LEFT is null) then
NCTRL_COEXEC := null;
else
if ((NCOEXEC_REST > 0) and (NDAYS_LEFT < NDAYS_LEFT_LIMIT)) then
NCTRL_COEXEC := 1;
else
NCTRL_COEXEC := 0;
end if;
end if;
/* Приведение значений */
NCOEXEC_IN := COALESCE(NCOEXEC_IN, 0);
end if;
end if;
end STAGE_CONTRACTS_GET;
/* Список договоров этапа проекта */
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.TDG_FILTERS; -- Фильтры
RO PKG_P8PANELS_VISUAL.TDG_ORDERS; -- Сортировки
RDG PKG_P8PANELS_VISUAL.TDG; -- Описание таблицы
RDG_ROW PKG_P8PANELS_VISUAL.TDG_ROW; -- Строка таблицы
RCOL_VALS PKG_P8PANELS_VISUAL.TDG_COL_VALS; -- Предопределённые значения столбцов
NROW_FROM PKG_STD.TREF; -- Номер строки с
NROW_TO PKG_STD.TREF; -- Номер строки по
CSQL clob; -- Буфер для запроса
ICURSOR integer; -- Курсор для исполнения запроса
NPROJECTSTAGEPF PKG_STD.TREF; -- Рег. номер соисполнителя этапа проекта
NPAY_IN PKG_STD.TNUMBER; -- Сведения о финансировании - сумма акцептованных счетов на оплату
NFIN_OUT PKG_STD.TNUMBER; -- Сведения о финансировании - сумма оплаченных счетов на оплату
NPAY_IN_REST PKG_STD.TNUMBER; -- Сведения о финансировании - сумма оставшихся к оплате счетов на оплату
NFIN_REST PKG_STD.TNUMBER; -- Сведения о финансировании - общий остаток к оплате по договору
NCTRL_FIN PKG_STD.TNUMBER; -- Сведения о финансировании - состояние (null - не определено, 0 - без отклонений, 1 - есть отклонения)
NCOEXEC_IN PKG_STD.TNUMBER; -- Сведения о соисполнении - получено актов/накладных
NCOEXEC_REST PKG_STD.TNUMBER; -- Сведения о соисполнении - остаток к актированию/поставке
NCTRL_COEXEC PKG_STD.TNUMBER; -- Сведения о соисполнении - состояние (null - не определено, 0 - без отклонений, 1 - есть отклонения)
begin
/* Читаем фильтры */
RF := PKG_P8PANELS_VISUAL.TDG_FILTERS_FROM_XML(CFILTERS => CFILTERS);
/* Читаем сортировки */
RO := PKG_P8PANELS_VISUAL.TDG_ORDERS_FROM_XML(CORDERS => CORDERS);
/* Преобразуем номер и размер страницы в номер строк с и по */
PKG_P8PANELS_VISUAL.UTL_ROWS_LIMITS_CALC(NPAGE_NUMBER => NPAGE_NUMBER,
NPAGE_SIZE => NPAGE_SIZE,
NROW_FROM => NROW_FROM,
NROW_TO => NROW_TO);
/* Инициализируем таблицу данных */
RDG := PKG_P8PANELS_VISUAL.TDG_MAKE();
/* Добавляем в таблицу описание колонок */
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NRN',
SCAPTION => 'Рег. номер',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_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.TDG_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.TDG_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.TDG_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.TDG_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.TDG_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.TDG_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.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SEXT_NUMBER',
SCAPTION => 'Внешний номер',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_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.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SAGENT_INN',
SCAPTION => 'ИНН соисполнителя',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SAGENT_KPP',
SCAPTION => 'КПП соисполнителя',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SGOVCNTRID',
SCAPTION => 'ИГК',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_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.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SCSTAGE_DESCRIPTION',
SCAPTION => 'Описание этапа',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_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.TDG_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.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NSUMM',
SCAPTION => 'Сумма',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SCURR',
SCAPTION => 'Валюта',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_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);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NPAY_IN',
SCAPTION => 'Акцептовано счетов на оплату',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NFIN_OUT',
SCAPTION => 'Оплачено счетов',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NPAY_IN_REST',
SCAPTION => 'Осталось оплатить счетов',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_COL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 0, BCLEAR => true);
PKG_P8PANELS_VISUAL.TDG_COL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 1);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NCTRL_FIN',
SCAPTION => 'Фин-е (исх.)',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
SCOND_FROM => 'EDCTRL_FIN',
BORDER => false,
BFILTER => true,
RCOL_VALS => RCOL_VALS,
SHINT => '<b>Финансирование (исходящее)</b> - контроль оплаты счетов, выставленных соисполнителем в рамках договора.<br>' ||
'<b style="color:red">Требует внимания</b> - не все выставленные соисполнителем акцептованные счета оплачены.<br>' ||
'<b style="color:green">В норме</b> - нет описанных выше отклонений.<br>' ||
'<b style="color:gray">Пусто</b> - в Системе не хватает данных для рассчёта. Убедитесь, что для договора с соисполнителем аккуратно ведётся учёт первичных документов оперативного учёта (входящих счетов на оплату).');
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NFIN_REST',
SCAPTION => 'Общий остаток к оплате по договору',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NCOEXEC_IN',
SCAPTION => 'Получено актов/накладных',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NCOEXEC_REST',
SCAPTION => 'Остаток к актированию/поставке',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NCTRL_COEXEC',
SCAPTION => 'Соисполнение',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
SCOND_FROM => 'EDCTRL_COEXEC',
BORDER => false,
BFILTER => true,
RCOL_VALS => RCOL_VALS,
SHINT => '<b>Соисполнение</b> - контроль исполнения обязательств по договору с соисполнителем.<br>' ||
'<b style="color:red">Требует внимания</b> - до окончания этапа проекта, в рамках которого действует соисполнение, осталось менее ' ||
TO_CHAR(NDAYS_LEFT_LIMIT) ||
' дней, при этом зафиксирован положительный остаток к поставке/актированию по договору.<br>' ||
'<b style="color:green">В норме</b> - нет описанных выше отклонений.<br>' ||
'<b style="color:gray">Пусто</b> - в Системе не хватает данных для рассчёта. Убедитесь, что для связанного этапа проекта задана плановая дата окончания, ' ||
'а по договору с соисполнителем аккуратно ведётся учёт первичных документов оперативного учёта (приходных накладных).');
/* Обходим данные */
begin
/* Добавляем подсказку совместимости */
CSQL := PKG_SQL_BUILD.COMPATIBLE(SSQL => CSQL);
/* Формируем запрос */
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => 'select *');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from (select D.*,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.SQLROWNUM() || ' NROW');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from (select PSPF.RN NRN,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' trim(CN.DOC_PREF) SDOC_PREF,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.WRAP_STR(SVALUE => 'Contracts') || ' SLNK_UNIT_SDOC_PREF,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' CN.RN NLNK_DOCUMENT_SDOC_PREF,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' trim(CN.DOC_NUMB) SDOC_NUMB,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.WRAP_STR(SVALUE => 'Contracts') || ' SLNK_UNIT_SDOC_NUMB,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' CN.RN NLNK_DOCUMENT_SDOC_NUMB,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' CN.DOC_DATE DDOC_DATE,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' CN.EXT_NUMBER SEXT_NUMBER,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' AG.AGNNAME SAGENT,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' AG.AGNIDNUMB SAGENT_INN,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' AG.REASON_CODE SAGENT_KPP,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' GC.CODE SGOVCNTRID,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' trim(ST.NUMB) SCSTAGE,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' ST.DESCRIPTION SCSTAGE_DESCRIPTION,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' ST.BEGIN_DATE DCSTAGE_BEGIN_DATE,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' ST.END_DATE DCSTAGE_END_DATE,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' PSPF.COST_PLAN NSUMM,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' CUR.INTCODE SCURR,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' ART.CODE SCOST_ART');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from PROJECTSTAGEPF PSPF');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' left outer join FPDARTCL ART on PSPF.COST_ARTICLE = ART.RN,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' STAGES ST,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' CONTRACTS CN');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' left outer join GOVCNTRID GC on CN.GOVCNTRID = GC.RN,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' AGNLIST AG,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' CURNAMES CUR');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' where PSPF.FACEACC = ST.FACEACC');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and ST.PRN = CN.RN');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and PSPF.PERFORMER = AG.RN');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and CN.CURRENCY = CUR.RN');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and exists (select null from V_USERPRIV UP where UP."CATALOG" = PSPF.CRN)');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and exists (select null from V_USERPRIV UP where UP.JUR_PERS = PSPF.JUR_PERS and UP.UNITCODE = ' || PKG_SQL_BUILD.WRAP_STR(SVALUE => 'Projects') || ')');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and exists (select null from V_USERPRIV UP where UP."CATALOG" = ST.CRN)');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and exists (select null from V_USERPRIV UP where UP.JUR_PERS = ST.JUR_PERS and UP.UNITCODE = ' || PKG_SQL_BUILD.WRAP_STR(SVALUE => 'Contracts') || ')');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and PSPF.RN in (select ID from COND_BROKER_IDSMART where IDENT = :NIDENT) %ORDER_BY%) D) F');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' where F.NROW between :NROW_FROM and :NROW_TO');
/* Учтём сортировки */
PKG_P8PANELS_VISUAL.TDG_ORDERS_SET_QUERY(RDATA_GRID => RDG,
RORDERS => RO,
SPATTERN => '%ORDER_BY%',
CSQL => CSQL);
/* Учтём фильтры */
PKG_P8PANELS_VISUAL.TDG_FILTERS_SET_QUERY(NIDENT => NIDENT,
NCOMPANY => NCOMPANY,
NPARENT => NSTAGE,
SUNIT => 'ProjectsStagesPerformers',
SPROCEDURE => PKG_SQL_BUILD.PKG_NAME(SNAME => '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);
PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 21);
/* Делаем выборку */
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 => NPROJECTSTAGEPF);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NRN', NVALUE => NPROJECTSTAGEPF, BCLEAR => true);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SDOC_PREF',
ICURSOR => ICURSOR,
NPOSITION => 2);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SLNK_UNIT_SDOC_PREF',
ICURSOR => ICURSOR,
NPOSITION => 3);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NLNK_DOCUMENT_SDOC_PREF',
ICURSOR => ICURSOR,
NPOSITION => 4);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SDOC_NUMB',
ICURSOR => ICURSOR,
NPOSITION => 5);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SLNK_UNIT_SDOC_NUMB',
ICURSOR => ICURSOR,
NPOSITION => 6);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NLNK_DOCUMENT_SDOC_NUMB',
ICURSOR => ICURSOR,
NPOSITION => 7);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLD(RROW => RDG_ROW,
SNAME => 'DDOC_DATE',
ICURSOR => ICURSOR,
NPOSITION => 8);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SEXT_NUMBER',
ICURSOR => ICURSOR,
NPOSITION => 9);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SAGENT',
ICURSOR => ICURSOR,
NPOSITION => 10);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SAGENT_INN',
ICURSOR => ICURSOR,
NPOSITION => 11);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SAGENT_KPP',
ICURSOR => ICURSOR,
NPOSITION => 12);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SGOVCNTRID',
ICURSOR => ICURSOR,
NPOSITION => 13);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SCSTAGE',
ICURSOR => ICURSOR,
NPOSITION => 14);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SCSTAGE_DESCRIPTION',
ICURSOR => ICURSOR,
NPOSITION => 15);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLD(RROW => RDG_ROW,
SNAME => 'DCSTAGE_BEGIN_DATE',
ICURSOR => ICURSOR,
NPOSITION => 16);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLD(RROW => RDG_ROW,
SNAME => 'DCSTAGE_END_DATE',
ICURSOR => ICURSOR,
NPOSITION => 17);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NSUMM',
ICURSOR => ICURSOR,
NPOSITION => 18);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SCURR',
ICURSOR => ICURSOR,
NPOSITION => 19);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SCOST_ART',
ICURSOR => ICURSOR,
NPOSITION => 20);
STAGE_CONTRACTS_GET(NPROJECTSTAGEPF => NPROJECTSTAGEPF,
NINC_FIN => 1,
NINC_COEXEC => 1,
NPAY_IN => NPAY_IN,
NFIN_OUT => NFIN_OUT,
NPAY_IN_REST => NPAY_IN_REST,
NFIN_REST => NFIN_REST,
NCTRL_FIN => NCTRL_FIN,
NCOEXEC_IN => NCOEXEC_IN,
NCOEXEC_REST => NCOEXEC_REST,
NCTRL_COEXEC => NCTRL_COEXEC);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NPAY_IN', NVALUE => NPAY_IN);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NFIN_OUT', NVALUE => NFIN_OUT);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NPAY_IN_REST', NVALUE => NPAY_IN_REST);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NCTRL_FIN', NVALUE => NCTRL_FIN);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NFIN_REST', NVALUE => NFIN_REST);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NCOEXEC_IN', NVALUE => NCOEXEC_IN);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NCOEXEC_REST', NVALUE => NCOEXEC_REST);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NCTRL_COEXEC', NVALUE => NCTRL_COEXEC);
/* Добавляем строку в таблицу */
PKG_P8PANELS_VISUAL.TDG_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
end loop;
/* Освобождаем курсор */
PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR);
exception
when others then
PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR);
raise;
end;
/* Сериализуем описание */
COUT := PKG_P8PANELS_VISUAL.TDG_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => NINCLUDE_DEF);
end STAGE_CONTRACTS_LIST;
/* Считывание записи работы проекта */
function JOBS_GET
(
NRN in number -- Рег. номер работы проекта
) return PROJECTJOB%rowtype -- Запись работы проекта
is
RRES PROJECTJOB%rowtype; -- Буфер для результата
begin
select PS.* into RRES from PROJECTJOB 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 => 'PROJECTJOB');
end JOBS_GET;
/* Получение даты начала периода балансировки */
function JB_GET_BEG
(
NIDENT in number -- Идентификатор процесса
) return date -- Дата начала периода балансировки
is
DRES PKG_STD.TLDATE; -- Буфер для результата
begin
select min(D.DMIN_BEG_PLAN)
into DRES
from (select min(P.BEGPLAN) DMIN_BEG_PLAN
from PROJECT P
where P.RN in (select T.PROJECT from P8PNL_JB_PRJCTS T where T.IDENT = NIDENT)
union all
select min(PS.BEGPLAN) DMIN_BEG_PLAN
from PROJECTSTAGE PS
where PS.PRN in (select T.PROJECT from P8PNL_JB_PRJCTS T where T.IDENT = NIDENT)
union all
select min(PJ.BEGPLAN) DMIN_BEG_PLAN
from PROJECTJOB PJ
where PJ.PRN in (select T.PROJECT from P8PNL_JB_PRJCTS T where T.IDENT = NIDENT)) D;
/* Проверим, что хоть что-то нашли */
if (DRES is null) then
P_EXCEPTION(0,
'Не удалось определить дату начала периода балансировки. Убедитесь, что для проектов, этапов и работ заданы плановые сроки начала.');
end if;
/* Вернём результат - первый день минимального месяца */
return TRUNC(DRES, 'mm');
end JB_GET_BEG;
/* Получение даты окончания периода балансировки */
function JB_GET_END
(
NIDENT in number -- Идентификатор процесса
) return date -- Дата окончания периода балансировки
is
DRES PKG_STD.TLDATE; -- Буфер для результата
begin
select max(D.DMAX_END_PLAN)
into DRES
from (select max(P.ENDPLAN) DMAX_END_PLAN
from PROJECT P
where P.RN in (select T.PROJECT from P8PNL_JB_PRJCTS T where T.IDENT = NIDENT)
union all
select max(PS.ENDPLAN) DMAX_END_PLAN
from PROJECTSTAGE PS
where PS.PRN in (select T.PROJECT from P8PNL_JB_PRJCTS T where T.IDENT = NIDENT)
union all
select max(PJ.ENDPLAN) DMAX_END_PLAN
from PROJECTJOB PJ
where PJ.PRN in (select T.PROJECT from P8PNL_JB_PRJCTS T where T.IDENT = NIDENT)) D;
/* Проверим, что хоть что-то нашли */
if (DRES is null) then
P_EXCEPTION(0,
'Не удалось определить дату окончания периода балансировки. Убедитесь, что для проектов, этапов и работ заданы плановые сроки окончания.');
end if;
/* Вернём результат - последний день максимального месяца */
return LAST_DAY(DRES);
end JB_GET_END;
/* Получение мнемокода единицы измерения длительности */
function JB_GET_DURATION_MEAS_CODE
(
NDURATION_MEAS in number -- Единица измерения длительности (0 - день, 1 - неделя, 2 - декада, 3 - месяц, 4 - квартал, 5 - год)
) return varchar2 -- Мнемокод единицы измерения длительности
is
begin
/* Результат от указанного кода ЕИ длительности */
case NDURATION_MEAS
/* Известные ЕИ */
when 0 then
return 'День';
when 1 then
return 'Неделя';
when 2 then
return 'Декада';
when 3 then
return 'Месяц';
when 4 then
return 'Квартал';
when 5 then
return 'Год';
/* Неизвестная ЕИ */
else
P_EXCEPTION(0,
'Единица измерения длительности "%s" не поддерживается.',
COALESCE(TO_CHAR(NDURATION_MEAS), '<НЕ УКАЗАНА>'));
end case;
end JB_GET_DURATION_MEAS_CODE;
/* Базовое добавление параметров балансировки */
procedure JB_PRMS_BASE_INSERT
(
NIDENT in number, -- Идентификатор процесса
DDATE_BEGIN in date, -- Дата начала периода балансировки
DDATE_FACT in date, -- Факт по состоянию на
NDURATION_MEAS in number, -- Единица измерения длительности (0 - день, 1 - неделя, 2 - декада, 3 - месяц, 4 - квартал, 5 - год)
SDURATION_MEAS_CODE in varchar2, -- Единица измерения длительности (мнемокод)
NLAB_MEAS in number, -- Единица измерения трудоёмкости
SLAB_MEAS_CODE in varchar2, -- Единица измерения трудоёмкости (мнемокод)
NRN out number -- Рег. номер записи
)
is
begin
/* Сформируем рег. номер */
NRN := GEN_ID();
/* Добавим запись */
insert into P8PNL_JB_PRMS
(RN, IDENT, DATE_BEGIN, DATE_FACT, DURATION_MEAS, DURATION_MEAS_CODE, LAB_MEAS, LAB_MEAS_CODE)
values
(NRN, NIDENT, DDATE_BEGIN, DDATE_FACT, NDURATION_MEAS, SDURATION_MEAS_CODE, NLAB_MEAS, SLAB_MEAS_CODE);
end JB_PRMS_BASE_INSERT;
/* Очистка параметров балансировки */
procedure JB_PRMS_CLEAN
(
NIDENT in number -- Идентификатор процесса
)
is
begin
/* Удаляем периоды балансировки */
delete from P8PNL_JB_PRMS T where T.IDENT = NIDENT;
end JB_PRMS_CLEAN;
/* Считывание записи параметров балансировки работ */
function JB_PRMS_GET
(
NIDENT in number -- Идентификатор процесса
) return P8PNL_JB_PRMS%rowtype -- Запись параметров
is
RRES P8PNL_JB_PRMS%rowtype; -- Буфер для результата
begin
select P.* into RRES from P8PNL_JB_PRMS P where P.IDENT = NIDENT;
return RRES;
exception
when NO_DATA_FOUND then
PKG_MSG.RECORD_NOT_FOUND(NFLAG_SMART => 0, NDOCUMENT => NIDENT, SUNIT_TABLE => 'P8PNL_JB_PRMS');
end JB_PRMS_GET;
/* Считывание записи проекта из буфера балансировки работ */
function JB_PRJCTS_GET
(
NJB_PRJCTS in number -- Рег. номер записи списка балансируемых проектов
) return P8PNL_JB_PRJCTS%rowtype -- Запись проекта
is
RRES P8PNL_JB_PRJCTS%rowtype; -- Буфер для результата
begin
select P.* into RRES from P8PNL_JB_PRJCTS P where P.RN = NJB_PRJCTS;
return RRES;
exception
when NO_DATA_FOUND then
PKG_MSG.RECORD_NOT_FOUND(NFLAG_SMART => 0, NDOCUMENT => NJB_PRJCTS, SUNIT_TABLE => 'P8PNL_JB_PRJCTS');
end JB_PRJCTS_GET;
/* Установка признака наличия изменений проекта, требующих сохранения */
procedure JB_PRJCTS_SET_CHANGED
(
NJB_PRJCTS in number, -- Рег. номер записи списка балансируемых проектов
NCHANGED in number -- Признак наличия изменений, требующих сохранения (0 - нет, 1 - да)
)
is
begin
/* Установим признак */
update P8PNL_JB_PRJCTS T set T.CHANGED = NCHANGED where T.RN = NJB_PRJCTS;
end JB_PRJCTS_SET_CHANGED;
/* Базовое добавление проекта для балансировки работ */
procedure JB_PRJCTS_BASE_INSERT
(
NIDENT in number, -- Идентификатор процесса
NPROJECT in number, -- Рег. номер проекта
NJOBS in number, -- Признак наличия плана-графика (0 - нет, 1 - да)
NEDITABLE in number, -- Признак возможности редактирования (0 - нет, 1 - да)
NCHANGED in number, -- Признак наличия изменений, требующих сохранения (0 - нет, 1 - да)
NJB_PRJCTS out number -- Рег. номер записи списка балансируемых проектов
)
is
begin
/* Сформируем рег. номер записи */
NJB_PRJCTS := GEN_ID();
/* Добавим запись */
insert into P8PNL_JB_PRJCTS
(RN, IDENT, PROJECT, JOBS, EDITABLE, CHANGED)
values
(NJB_PRJCTS, NIDENT, NPROJECT, NJOBS, NEDITABLE, NCHANGED);
end JB_PRJCTS_BASE_INSERT;
/* Получение списка проектов */
procedure JB_PRJCTS_LIST
(
NIDENT in number, -- Идентификатор процесса
COUT out clob -- Список проектов
)
is
begin
/* Начинаем формирование XML */
PKG_XFAST.PROLOGUE(ITYPE => PKG_XFAST.CONTENT_);
/* Открываем корень */
PKG_XFAST.DOWN_NODE(SNAME => 'XDATA');
/* Обходим буфер балансировки */
for C in (select T.RN NRN,
T.PROJECT NPROJECT,
P.NAME_USL SNAME,
T.JOBS NJOBS,
T.EDITABLE NEDITABLE,
T.CHANGED NCHANGED
from P8PNL_JB_PRJCTS T,
PROJECT P
where T.IDENT = NIDENT
and T.PROJECT = P.RN
and exists (select null from V_USERPRIV UP where UP.CATALOG = P.CRN)
and exists (select null
from V_USERPRIV UP
where UP.JUR_PERS = P.JUR_PERS
and UP.UNITCODE = 'Projects')
order by T.RN)
loop
/* Открываем проект */
PKG_XFAST.DOWN_NODE(SNAME => 'XPROJECTS');
/* Описываем проект */
PKG_XFAST.ATTR(SNAME => 'NRN', NVALUE => C.NRN);
PKG_XFAST.ATTR(SNAME => 'NPROJECT', NVALUE => C.NPROJECT);
PKG_XFAST.ATTR(SNAME => 'SNAME', SVALUE => C.SNAME);
PKG_XFAST.ATTR(SNAME => 'NJOBS', NVALUE => C.NJOBS);
PKG_XFAST.ATTR(SNAME => 'NEDITABLE', NVALUE => C.NEDITABLE);
PKG_XFAST.ATTR(SNAME => 'NCHANGED', NVALUE => C.NCHANGED);
/* Закрываем проект */
PKG_XFAST.UP();
end loop;
/* Закрываем корень */
PKG_XFAST.UP();
/* Сериализуем */
COUT := PKG_XFAST.SERIALIZE_TO_CLOB();
/* Завершаем формирование XML */
PKG_XFAST.EPILOGUE();
exception
when others then
/* Завершаем формирование XML */
PKG_XFAST.EPILOGUE();
/* Вернем ошибку */
PKG_STATE.DIAGNOSTICS_STACKED();
P_EXCEPTION(0, PKG_STATE.SQL_ERRM());
end JB_PRJCTS_LIST;
/* Считывание записи работы/этапа из буфера балансировки работ */
function JB_JOBS_GET
(
NJB_JOBS in number -- Рег. номер записи работы/этапа в буфере балансировки работ
) return P8PNL_JB_JOBS%rowtype -- Найденная запись
is
RRES P8PNL_JB_JOBS%rowtype; -- Буфер для результата
begin
select P.* into RRES from P8PNL_JB_JOBS P where P.RN = NJB_JOBS;
return RRES;
exception
when NO_DATA_FOUND then
PKG_MSG.RECORD_NOT_FOUND(NFLAG_SMART => 0, NDOCUMENT => NJB_JOBS, SUNIT_TABLE => 'P8PNL_JB_JOBS');
end JB_JOBS_GET;
/* Поиск записи работы/этапа в списке балансировки по этапу/работе проекта */
function JB_JOBS_GET_BY_SOURCE
(
NIDENT in number, -- Идентификатор процесса
NPRN in number, -- Рег. номер родителя
NSOURCE in number -- Рег. номер источника (работы/этапа проекта)
) return P8PNL_JB_JOBS%rowtype -- Найденная запись
is
RRES P8PNL_JB_JOBS%rowtype; -- Буфер для результата
begin
select T.*
into RRES
from P8PNL_JB_JOBS T
where T.IDENT = NIDENT
and T.PRN = NPRN
and T.SOURCE = NSOURCE;
return RRES;
exception
when NO_DATA_FOUND then
P_EXCEPTION(0,
'Запись работы/этапа (RN-источника: %s) не определена в буфере балансировки.',
COALESCE(TO_CHAR(NSOURCE), '<НЕ УКАЗАН>'));
end JB_JOBS_GET_BY_SOURCE;
/* Установка признака наличия изменений балансируемой работы/этапа, требующих сохранения */
procedure JB_JOBS_SET_CHANGED
(
NJB_JOBS in number, -- Рег. номер записи балансируемой работы/этапа
NCHANGED in number -- Признак наличия изменений, требующих сохранения (0 - нет, 1 - да)
)
is
begin
/* Установим признак */
update P8PNL_JB_JOBS T set T.CHANGED = NCHANGED where T.RN = NJB_JOBS;
end JB_JOBS_SET_CHANGED;
/* Базовое добавление работы/этапа для балансировки работ */
procedure JB_JOBS_BASE_INSERT
(
NIDENT in number, -- Идентификатор процесса
NPRN in number, -- Рег. номер родителя
NHRN in number, -- Рег. номер родительской записи в иерархии работ/этапов
NSOURCE in number, -- Рег. номер источника (работы/этапа проекта)
SNUMB in varchar2, -- Номер
SNAME in varchar2, -- Наименование
DDATE_FROM in date, -- Начало
DDATE_TO in date, -- Окончание
NDURATION in number, -- Длительность
SEXECUTOR in varchar2, -- Исполнитель
NSTAGE in number, -- Признак этапа (0 - нет, 1 - да)
NEDITABLE in number, -- Признак возможности редактирования (0 - нет, 1 - да)
NJB_JOBS out number -- Рег. номер записи балансируемой работы/этапа
)
is
begin
/* Сформируем рег. номер записи */
NJB_JOBS := GEN_ID();
/* Добавим запись */
insert into P8PNL_JB_JOBS
(RN, IDENT, PRN, HRN, source, NUMB, name, DATE_FROM, DATE_TO, DURATION, EXECUTOR, STAGE, EDITABLE)
values
(NJB_JOBS, NIDENT, NPRN, NHRN, NSOURCE, SNUMB, SNAME, DDATE_FROM, DDATE_TO, NDURATION, SEXECUTOR, NSTAGE, NEDITABLE);
end JB_JOBS_BASE_INSERT;
/* Базовое изменение сроков работы в буфере балансировки */
procedure JB_JOBS_BASE_MODIFY_PERIOD
(
NJB_JOBS in number, -- Рег. номер записи балансируемой работы/этапа
NDELTA in number, -- Изменение срока работы
NCHANGE_FLAG in number -- Флаг изменения данных (1 - изменять дату начала, 2 - изменять дату окончания)
)
is
RJ PROJECTJOB%rowtype; -- Запись работы в проекте
RS PROJECTSTAGE%rowtype; -- Запись этапа в проекте
RJB_J P8PNL_JB_JOBS%rowtype; -- Запись работы в буфере балансировки
RJB_PRMS P8PNL_JB_PRMS%rowtype; -- Параметры балансировки
DDATE_FROM_NEW PKG_STD.TLDATE; -- Новая дата начала работы
DDATE_TO_NEW PKG_STD.TLDATE; -- Новая дата окончания работы
begin
/* Считаем работу из буфера */
RJB_J := JB_JOBS_GET(NJB_JOBS => NJB_JOBS);
/* Считаем параметры балансировки */
RJB_PRMS := JB_PRMS_GET(NIDENT => RJB_J.IDENT);
/* Считаем работу проекта */
RJ := JOBS_GET(NRN => RJB_J.SOURCE);
/* Проверки - работа должна быть привязана к этапу */
if (RJ.PROJECTSTAGE is null) then
P_EXCEPTION(0,
'Работа "%s" должа быть привязана к этапу проекта.',
trim(RJ.NUMB));
end if;
/* Считаем этап проекта */
RS := STAGES_GET(NRN => RJ.PROJECTSTAGE);
/* Проверки - работа должна иметь фиксированную длительность */
if (RJ.DURATION_CHG <> 2) then
P_EXCEPTION(0,
'Работа "%s" должна иметь фиксированную длительность.',
trim(RJ.NUMB));
end if;
/* Проверки - работа должна быть в состоянии отличном от "Неначата" */
if (RJ.STATE <> 0) then
P_EXCEPTION(0,
'Работа "%s" должна быть в состоянии "Не начата".',
trim(RJ.NUMB));
end if;
/* Вычислим новую дату начала и окончания для работы */
if (NCHANGE_FLAG = 1) then
DDATE_FROM_NEW := RJB_J.DATE_FROM + NDELTA;
P_PROJECTJOB_GET_OFFSET_DATE(NCOMPANY => RJ.COMPANY,
DSRC_DATE => DDATE_FROM_NEW,
NOFFSET => RJ.DURATION_P,
NOFFSET_MEAS => RJB_PRMS.DURATION_MEAS,
DDEST_DATE => DDATE_TO_NEW);
else
DDATE_TO_NEW := RJB_J.DATE_TO + NDELTA;
P_PROJECTJOB_GET_OFFSET_DATE(NCOMPANY => RJ.COMPANY,
DSRC_DATE => DDATE_TO_NEW,
NOFFSET => -RJ.DURATION_P,
NOFFSET_MEAS => RJB_PRMS.DURATION_MEAS,
DDEST_DATE => DDATE_FROM_NEW);
end if;
/* Проверки - дата начала работы не должна быть меньше даты факта */
if ((NCHANGE_FLAG = 1) and (DDATE_FROM_NEW <= RJB_PRMS.DATE_FACT)) then
P_EXCEPTION(0,
'Работа не может начинаться раньше даты "Факт по состоянию на" (%s).',
TO_CHAR(RJB_PRMS.DATE_FACT, 'DD.MM.YYYY'));
end if;
/* Проверки - дата окончания работы не должна быть меньше даты факта */
if ((NCHANGE_FLAG = 2) and (DDATE_TO_NEW <= RJB_PRMS.DATE_FACT)) then
P_EXCEPTION(0,
'Работа не может заканчиваться раньше даты "Факт по состоянию на" (%s).',
TO_CHAR(RJB_PRMS.DATE_FACT, 'DD.MM.YYYY'));
end if;
/* Проверки - дата окончания работы не должна быть больше даты окончания этапа */
if ((NCHANGE_FLAG = 2) and (DDATE_TO_NEW >= RS.ENDPLAN)) then
P_EXCEPTION(0,
'Работа не может заканчиваться после даты завершения этапа (%s).',
TO_CHAR(RS.ENDPLAN, 'DD.MM.YYYY'));
end if;
/* Изменяем работу */
update P8PNL_JB_JOBS T
set T.DATE_FROM = DDATE_FROM_NEW,
T.DATE_TO = DDATE_TO_NEW
where T.RN = RJB_J.RN;
/* Установим признак наличия изменений */
JB_JOBS_SET_CHANGED(NJB_JOBS => RJB_J.RN, NCHANGED => 1);
/* Обходим зависимые работы с фиксированной длительностью и меняем их */
for C in (select J.RN
from P8PNL_JB_JOBS J
where J.RN in (select PRV.PRN
from P8PNL_JB_JOBSPREV PRV
where PRV.IDENT = RJB_J.IDENT
and PRV.JB_JOBS = RJB_J.RN))
loop
JB_JOBS_BASE_MODIFY_PERIOD(NJB_JOBS => C.RN, NDELTA => NDELTA, NCHANGE_FLAG => NCHANGE_FLAG);
end loop;
end JB_JOBS_BASE_MODIFY_PERIOD;
/* Изменение сроков работы в буфере балансировки */
procedure JB_JOBS_MODIFY_PERIOD
(
NJB_JOBS in number, -- Рег. номер записи балансируемой работы/этапа
DDATE_FROM in date, -- Новая дата начала
DDATE_TO in date, -- Новая дата окончания
NRESOURCE_STATUS out number -- Состояние ресурсов (0 - без отклонений, 1 - есть отклонения, -1 - ничего не изменяли)
)
is
RJB_J P8PNL_JB_JOBS%rowtype; -- Запись работы в буфере балансировки
RJB_P P8PNL_JB_PRJCTS%rowtype; -- Запись родительского проекта в буфере балансировки
RJ PROJECTJOB%rowtype; -- Запись работы в проекте
NCHANGE_FLAG PKG_STD.TNUMBER := 0; -- Флаг изменения данных (0 - нечего менять, 1 - дата начала изменилась, 2 - дата окончания изменилась)
NDELTA PKG_STD.TNUMBER; -- Изменение даты
SUTILIZER PKG_STD.TSTRING := UTILIZER(); -- Пользователь сеанса
begin
/* Считаем работу из буфера */
RJB_J := JB_JOBS_GET(NJB_JOBS => NJB_JOBS);
/* Считаем проект из буфера */
RJB_P := JB_PRJCTS_GET(NJB_PRJCTS => RJB_J.PRN);
/* Считаем работу проекта */
RJ := JOBS_GET(NRN => RJB_J.SOURCE);
/* Проверки - это должна быть работа */
if (RJB_J.STAGE = 1) then
P_EXCEPTION(0, 'Изменение сроков допустимо только для работ.');
end if;
/* Проверки - пользователь должен быть ответственным за проект */
if (CHECK_RESPONSIBLE(NRN => RJB_P.PROJECT, SAUTHID => SUTILIZER) <> 1) then
P_EXCEPTION(0, 'Вы не являетесь ответственным за данный проект.');
end if;
/* Проверки - работа должна иметь фиксированную длительность */
if (RJ.DURATION_CHG <> 2) then
P_EXCEPTION(0, 'Работа должна иметь фиксированную длительность.');
end if;
/* Определимся с тем, что будем менять и на сколько */
if ((DDATE_FROM is not null) and (TRUNC(RJB_J.DATE_FROM) <> TRUNC(DDATE_FROM))) then
NCHANGE_FLAG := 1;
NDELTA := TRUNC(DDATE_FROM) - TRUNC(RJB_J.DATE_FROM);
end if;
if ((DDATE_TO is not null) and (TRUNC(RJB_J.DATE_TO) <> TRUNC(DDATE_TO)) and (NCHANGE_FLAG = 0)) then
NCHANGE_FLAG := 2;
NDELTA := TRUNC(DDATE_TO) - TRUNC(RJB_J.DATE_TO);
end if;
/* Если есть что менять */
if (NCHANGE_FLAG <> 0) then
/* Изменяем работы */
JB_JOBS_BASE_MODIFY_PERIOD(NJB_JOBS => RJB_J.RN,
NDELTA => NDELTA,
NCHANGE_FLAG => NCHANGE_FLAG);
/* Выставим признак изменений в проекте */
JB_PRJCTS_SET_CHANGED(NJB_PRJCTS => RJB_P.RN, NCHANGED => 1);
/* Выполним пересчёт монитора */
JB_PERIODS_RECALC(NIDENT => RJB_P.IDENT, NINITIAL => 0, NRESOURCE_STATUS => NRESOURCE_STATUS);
else
/* Ничего не изменили */
NRESOURCE_STATUS := -1;
end if;
end JB_JOBS_MODIFY_PERIOD;
/* Получение списка работ проектов для диаграммы Ганта */
procedure JB_JOBS_LIST
(
NIDENT in number, -- Идентификатор процесса
NPRN in number, -- Рег. номер родителя
NINCLUDE_DEF in number, -- Признак включения описания диаграммы в ответ
COUT out clob -- Список проектов
)
is
/* Константы */
SBG_COLOR_DANGER constant PKG_STD.TSTRING := '#ff4d4d'; -- Цвет заливки проблемных задач
SBG_COLOR_WARN constant PKG_STD.TSTRING := 'orange'; -- Цвет заливки задач с предупреждениями
SBG_COLOR_OK constant PKG_STD.TSTRING := 'lightgreen'; -- Цвет заливки беспроблемных задач
SBG_COLOR_DISABLED constant PKG_STD.TSTRING := 'darkgrey'; -- Цвет заливки невыполняемых задач
SBG_COLOR_STAGE constant PKG_STD.TSTRING := 'cadetblue'; -- Цвет заливки этапов
STEXT_COLOR_DANGER constant PKG_STD.TSTRING := 'blue'; -- Цвет текста задач с предупреждениями
/* Переменные */
RJB_PRJ P8PNL_JB_PRJCTS%rowtype; -- Родительская запись буфера балансировки
RPRJ PROJECT%rowtype; -- Запись проекта
RSTG PROJECTSTAGE%rowtype; -- Запись этапа
RJOB PROJECTJOB%rowtype; -- Запись работы
RG PKG_P8PANELS_VISUAL.TGANTT; -- Описание диаграммы Ганта
RGT PKG_P8PANELS_VISUAL.TGANTT_TASK; -- Описание задачи для диаграммы
STITLE PKG_STD.TSTRING; -- Общий заголовок
BREAD_ONLY_DATES boolean := false; -- Флаг доступности дат проекта только для чтения
BTASK_READ_ONLY boolean; -- Флаг доступности задачи только для чтения
STASK_BG_COLOR PKG_STD.TSTRING; -- Цвет фона задачи
STASK_TEXT_COLOR PKG_STD.TSTRING; -- Цвет текста задачи
STASK_CAPTION PKG_STD.TSTRING; -- Заголовок задачи
NTASK_STATE PKG_STD.TNUMBER; -- Состояние задачи
NTASK_PROGRESS PKG_STD.TNUMBER; -- Прогресс выполнения задачи
STASK_RESP PKG_STD.TSTRING; -- Ответственный за исполнение задачи
begin
/* Читаем родительскую запись буфера балансировки */
RJB_PRJ := JB_PRJCTS_GET(NJB_PRJCTS => NPRN);
/* Читаем запись проекта */
RPRJ := GET(NRN => RJB_PRJ.PROJECT);
/* Определимся с возможностью изменения данных проекта */
if (RJB_PRJ.EDITABLE = 0) then
BREAD_ONLY_DATES := true;
end if;
/* Сформируем общий заголовок */
STITLE := RPRJ.NAME_USL || ' - ' || RPRJ.NAME;
if ((RPRJ.EXT_CUST is not null) or ((RPRJ.BEGPLAN is not null) and (RPRJ.ENDPLAN is not null))) then
STITLE := STITLE || ' (';
if (RPRJ.EXT_CUST is not null) then
STITLE := STITLE || 'заказчик: "' ||
COALESCE(GET_AGNLIST_AGNABBR_ID(NFLAG_SMART => 1, NRN => RPRJ.EXT_CUST), '<НЕ ОПРЕДЕЛЁН>') || '", ';
end if;
if ((RPRJ.BEGPLAN is not null) and (RPRJ.ENDPLAN is not null)) then
STITLE := STITLE || 'с ' || TO_CHAR(RPRJ.BEGPLAN, 'dd.mm.yyyy') || ' по ' ||
TO_CHAR(RPRJ.ENDPLAN, 'dd.mm.yyyy');
end if;
STITLE := STITLE || ')';
end if;
/* Инициализируем диаграмму Ганта */
RG := PKG_P8PANELS_VISUAL.TGANTT_MAKE(STITLE => STITLE,
NZOOM => PKG_P8PANELS_VISUAL.NGANTT_ZOOM_MONTH,
BREAD_ONLY_DATES => BREAD_ONLY_DATES,
BREAD_ONLY_PROGRESS => true);
/* Добавим динамические атрибуты к задачам */
PKG_P8PANELS_VISUAL.TGANTT_ADD_TASK_ATTR(RGANTT => RG, SNAME => 'type', SCAPTION => 'Тип');
PKG_P8PANELS_VISUAL.TGANTT_ADD_TASK_ATTR(RGANTT => RG, SNAME => 'state', SCAPTION => 'Состояние');
PKG_P8PANELS_VISUAL.TGANTT_ADD_TASK_ATTR(RGANTT => RG, SNAME => 'resp', SCAPTION => 'Ответственный');
/* Добавим описание цветов задач */
PKG_P8PANELS_VISUAL.TGANTT_ADD_TASK_COLOR(RGANTT => RG,
SBG_COLOR => SBG_COLOR_DANGER,
STEXT_COLOR => STEXT_COLOR_DANGER,
SDESC => 'Для задач в состоянии "Не начата" - срыв срока начала, есть угроза срыва сроков окончания задачи. ' ||
'Для задач в состоянии "Выполняется", "Остановлена" - срыв срока окончания, есть угроза срыва срока окончания этапа/проекта.');
PKG_P8PANELS_VISUAL.TGANTT_ADD_TASK_COLOR(RGANTT => RG,
SBG_COLOR => SBG_COLOR_WARN,
SDESC => 'Для задач в состоянии "Не начата" - приближается срок начала, важно обеспечить своевременное выполнение работ. ' ||
'Для задач в состоянии "Выполняется", "Остановлена" - приближается срок окончания, важно обеспечить своевременное завершение работ.');
PKG_P8PANELS_VISUAL.TGANTT_ADD_TASK_COLOR(RGANTT => RG,
SBG_COLOR => SBG_COLOR_OK,
SDESC => 'Сроки исполнения задачи не вызывают опасений.');
PKG_P8PANELS_VISUAL.TGANTT_ADD_TASK_COLOR(RGANTT => RG,
SBG_COLOR => SBG_COLOR_DISABLED,
SDESC => 'Задача не выполняется (она в состоянии "Выполнена" или "Отменена").');
PKG_P8PANELS_VISUAL.TGANTT_ADD_TASK_COLOR(RGANTT => RG,
SBG_COLOR => SBG_COLOR_STAGE,
SDESC => 'Этим цветом выделены этапы.');
/* Обходим работы */
for C in (select JB.*
from P8PNL_JB_JOBS JB,
P8PNL_JB_PRJCTS PB,
PROJECT P
where JB.IDENT = NIDENT
and JB.PRN = NPRN
and JB.PRN = PB.RN
and PB.PROJECT = P.RN
and exists (select null from V_USERPRIV UP where UP.CATALOG = P.CRN)
and exists (select null
from V_USERPRIV UP
where UP.JUR_PERS = P.JUR_PERS
and UP.UNITCODE = 'Projects')
order by JB.RN)
loop
/* Считаем источник - этап или работу проекта, здесь же найдём ответственного */
STASK_RESP := null;
if (C.STAGE = 1) then
RSTG := STAGES_GET(NRN => C.SOURCE);
if (RSTG.RESPONSIBLE is not null) then
STASK_RESP := GET_AGNLIST_AGNABBR_ID(NFLAG_SMART => 1, NRN => RSTG.RESPONSIBLE);
elsif (RSTG.SUBDIV_RESP is not null) then
STASK_RESP := UTL_INS_DEPARTMENT_GET_NAME(NRN => RSTG.SUBDIV_RESP);
end if;
else
RJOB := JOBS_GET(NRN => C.SOURCE);
if (RJOB.PERFORM is not null) then
STASK_RESP := GET_AGNLIST_AGNABBR_ID(NFLAG_SMART => 1, NRN => RJOB.PERFORM);
elsif (RJOB.SUBDIV is not null) then
STASK_RESP := UTL_INS_DEPARTMENT_GET_NAME(NRN => RJOB.SUBDIV);
end if;
end if;
/* Определимся с состоянием */
if (C.STAGE = 1) then
NTASK_STATE := RSTG.STATE;
else
NTASK_STATE := RJOB.STATE;
end if;
/* Определимся с форматированием */
if (C.STAGE = 1) then
/* Этапы всегда одинаково красим */
STASK_BG_COLOR := SBG_COLOR_STAGE;
else
/* Сбросим цвета от предыдущей работы (на всякий случай) */
STASK_BG_COLOR := null;
STASK_TEXT_COLOR := null;
/* Работы - от статуса ("Не начата") */
if (RJOB.STATE = 0) then
if (C.DATE_FROM <= sysdate) then
STASK_BG_COLOR := SBG_COLOR_DANGER;
STASK_TEXT_COLOR := STEXT_COLOR_DANGER;
elsif (C.DATE_FROM <= sysdate + NDAYS_LEFT_LIMIT) then
STASK_BG_COLOR := SBG_COLOR_WARN;
else
STASK_BG_COLOR := SBG_COLOR_OK;
end if;
end if;
/* Работы - от статуса ("Выполняется", "Остановлена") */
if (RJOB.STATE in (1, 3)) then
if (C.DATE_TO <= sysdate) then
STASK_BG_COLOR := SBG_COLOR_DANGER;
STASK_TEXT_COLOR := STEXT_COLOR_DANGER;
elsif (C.DATE_TO <= sysdate + NDAYS_LEFT_LIMIT) then
STASK_BG_COLOR := SBG_COLOR_WARN;
else
STASK_BG_COLOR := SBG_COLOR_OK;
end if;
end if;
/* Работы - от статуса ("Выполнена", "Отменена") */
if (RJOB.STATE in (2, 4)) then
/* Всегда тёмные */
STASK_BG_COLOR := SBG_COLOR_DISABLED;
end if;
end if;
/* Определимся с возможностью редактирования */
BTASK_READ_ONLY := false;
if (C.EDITABLE = 0) then
BTASK_READ_ONLY := true;
end if;
/* Сформируем заголовок для выдачи в диаграмме */
STASK_CAPTION := trim(C.NUMB) || ' - ' || C.NAME;
if (LENGTH(STASK_CAPTION) > NGANTT_TASK_CAPTION_LEN) then
STASK_CAPTION := SUBSTR(STASK_CAPTION, 1, NGANTT_TASK_CAPTION_LEN) || '...';
end if;
/* Определим прогресс (только для работ в статусах "Выполняется" и "Остановлена") */
if ((C.STAGE = 0) and (RJOB.STATE in (1, 3)) and (RJOB.LAB_PLAN > 0)) then
NTASK_PROGRESS := RJOB.LAB_FACT / RJOB.LAB_PLAN * 100;
else
NTASK_PROGRESS := null;
end if;
/* Сформируем работу */
RGT := PKG_P8PANELS_VISUAL.TGANTT_TASK_MAKE(NRN => C.RN,
SNUMB => C.NUMB,
SCAPTION => STASK_CAPTION,
SNAME => C.NAME,
DSTART => C.DATE_FROM,
DEND => C.DATE_TO,
NPROGRESS => NTASK_PROGRESS,
SBG_COLOR => STASK_BG_COLOR,
STEXT_COLOR => STASK_TEXT_COLOR,
BREAD_ONLY => BTASK_READ_ONLY,
BREAD_ONLY_PROGRESS => true);
PKG_P8PANELS_VISUAL.TGANTT_TASK_ADD_ATTR_VAL(RGANTT => RG,
RTASK => RGT,
SNAME => 'type',
SVALUE => C.STAGE,
BCLEAR => true);
PKG_P8PANELS_VISUAL.TGANTT_TASK_ADD_ATTR_VAL(RGANTT => RG, RTASK => RGT, SNAME => 'state', SVALUE => NTASK_STATE);
PKG_P8PANELS_VISUAL.TGANTT_TASK_ADD_ATTR_VAL(RGANTT => RG, RTASK => RGT, SNAME => 'resp', SVALUE => STASK_RESP);
/* Определимся с предшествующими работами */
for CP in (select JP.JB_JOBS
from P8PNL_JB_JOBSPREV JP
where JP.IDENT = NIDENT
and JP.PRN = C.RN)
loop
PKG_P8PANELS_VISUAL.TGANTT_TASK_ADD_DEPENDENCY(RTASK => RGT, NDEPENDENCY => CP.JB_JOBS);
end loop;
/* Добавляем работу в диаграмму */
PKG_P8PANELS_VISUAL.TGANTT_ADD_TASK(RGANTT => RG, RTASK => RGT);
end loop;
/* Проверим, что есть хоть что-то для отображения */
if (RG.RTASKS.COUNT = 0) then
P_EXCEPTION(0,
'Для проекта не определены этапы/работы, отображение которых допустимо в диаграмме (убедитесь, что для них в учётных данных заданы плановые даты начала/окончания).');
end if;
/* Формируем список */
COUT := PKG_P8PANELS_VISUAL.TGANTT_TO_XML(RGANTT => RG, NINCLUDE_DEF => NINCLUDE_DEF);
end JB_JOBS_LIST;
/* Базовое добавление предшествующей работы/этапа для балансировки работ */
procedure JB_JOBSPREV_BASE_INSERT
(
NIDENT in number, -- Идентификатор процесса
NPRN in number, -- Рег. номер родителя
NJB_JOBS in number, -- Рег. номер предшествующей работы/этапа
NJB_JOBSPREV out number -- Рег. номер записи предшествующей балансируемой работы/этапа
)
is
begin
/* Сформируем рег. номер записи */
NJB_JOBSPREV := GEN_ID();
/* Добавим запись */
insert into P8PNL_JB_JOBSPREV (RN, IDENT, PRN, JB_JOBS) values (NJB_JOBSPREV, NIDENT, NPRN, NJB_JOBS);
end JB_JOBSPREV_BASE_INSERT;
/* Считывание записи периода из буфера балансировки работ */
function JB_PERIODS_GET
(
NJB_PERIODS in number -- Рег. номер записи периода в буфере балансировки
) return P8PNL_JB_PERIODS%rowtype -- Запись периода
is
RRES P8PNL_JB_PERIODS%rowtype; -- Буфер для результата
begin
select P.* into RRES from P8PNL_JB_PERIODS P where P.RN = NJB_PERIODS;
return RRES;
exception
when NO_DATA_FOUND then
PKG_MSG.RECORD_NOT_FOUND(NFLAG_SMART => 0, NDOCUMENT => NJB_PERIODS, SUNIT_TABLE => 'P8PNL_JB_PERIODS');
end JB_PERIODS_GET;
/* Формирование и расчет списка для детализации трудоёмкости по ФОТ периода балансировки */
procedure JB_PERIODS_PLAN_FOT_BUILD
(
NJB_PERIODS in number, -- Рег. номер записи периода в буфере балансировки
NMODE in number := 0, -- Режим (0 - список для клиента, 1 - только расчёты)
NPAGE_NUMBER in number := 0, -- Номер страницы (игнорируется при NPAGE_SIZE=0 и NMODE = 1)
NPAGE_SIZE in number := 0, -- Количество записей на странице (0 - все, игнорируется при NMODE = 1)
CORDERS in clob := null, -- Сортировки (игнорируется при NMODE = 1)
NINCLUDE_DEF in number := 1, -- Признак включения описания колонок таблицы в ответ (игнорируется при NMODE = 1)
NLAB_PLAN_FOT out number, -- Плановая трудоёмкость согласно ФОТ
COUT out clob -- Сериализованная таблица данных (заполняется только при NMODE = 0)
)
is
NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса
RPRD P8PNL_JB_PERIODS%rowtype; -- Запись детализируемого периода
RJB_PRMS P8PNL_JB_PRMS%rowtype; -- Параметры балансировки
RO PKG_P8PANELS_VISUAL.TDG_ORDERS; -- Сортировки
RDG PKG_P8PANELS_VISUAL.TDG; -- Описание таблицы
RDG_ROW PKG_P8PANELS_VISUAL.TDG_ROW; -- Строка таблицы
CSQL clob; -- Буфер для запроса
ICURSOR integer; -- Курсор для исполнения запроса
NROW_FROM PKG_STD.TREF; -- Номер строки с
NROW_TO PKG_STD.TREF; -- Номер строки по
NPERS_LAB PKG_STD.TLNUMBER; -- Трудоёмкость текущего сотрудника
NLAB_MEAS_HOURS PKG_STD.TREF; -- Рег. номер ЕИ трудоёмкости для человеко/часов
begin
/* Определим рег. номер ЕИ трудоёскости для человеко/часов */
FIND_DICMUNTS_BY_MNEMO(NFLAG_SMART => 0,
NCOMPANY => NCOMPANY,
SMEAS_MNEMO => SLAB_MEAS_HOURS,
NRN => NLAB_MEAS_HOURS);
/* Инициализируем сумму плановой трудоёмкости по ФОТ */
NLAB_PLAN_FOT := 0;
/* Считаем детализируемую запись периода */
RPRD := JB_PERIODS_GET(NJB_PERIODS => NJB_PERIODS);
/* Считаем параметры балансировки */
RJB_PRMS := JB_PRMS_GET(NIDENT => RPRD.IDENT);
/* Если не формируем данные для клиента */
if (NMODE = 1) then
/* Преобразуем номер и размер страницы в номер строк с и по - нам нужны все записи */
PKG_P8PANELS_VISUAL.UTL_ROWS_LIMITS_CALC(NPAGE_NUMBER => 0,
NPAGE_SIZE => 0,
NROW_FROM => NROW_FROM,
NROW_TO => NROW_TO);
else
/* Будем строить курсор по параметрам - читаем сортировки */
RO := PKG_P8PANELS_VISUAL.TDG_ORDERS_FROM_XML(CORDERS => CORDERS);
/* Преобразуем номер и размер страницы в номер строк с и по */
PKG_P8PANELS_VISUAL.UTL_ROWS_LIMITS_CALC(NPAGE_NUMBER => NPAGE_NUMBER,
NPAGE_SIZE => NPAGE_SIZE,
NROW_FROM => NROW_FROM,
NROW_TO => NROW_TO);
/* Инициализируем таблицу данных */
RDG := PKG_P8PANELS_VISUAL.TDG_MAKE();
/* Добавляем в таблицу описание колонок */
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NRN',
SCAPTION => 'Рег. номер исполнения должности',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SPERSON',
SCAPTION => 'Сотрудник',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BORDER => true);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NLAB_PLAN_FOT',
SCAPTION => 'Трудоёмкость (' || RJB_PRMS.LAB_MEAS_CODE || ')',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BORDER => true);
end if;
/* Обходим данные */
begin
/* Добавляем подсказку совместимости */
CSQL := PKG_SQL_BUILD.COMPATIBLE(SSQL => CSQL);
/* Формируем запрос */
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => 'select *');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from (select D.*,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.SQLROWNUM() || ' NROW');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from (select FM.RN NRN,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' PERS.CODE SPERSON,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' SH.AVG_HOURS NLAB_PLAN_FOT');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from CLNPSPFM FM,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' CLNPERSONS PERS,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' CLNPSDEP PSD,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' PRPROF PROF,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' CLNPSPFMHS FMH,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' SLSCHEDULE SH');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' where FM.COMPANY = :NCOMPANY');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and FM.PERSRN = PERS.RN');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and FM.DEPTRN = :NINS_DEPARTMENT');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and FM.PSDEPRN = PSD.RN');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and PSD.PRPROF = PROF.RN');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and PROF.RN in (select MP.PRPROF from FCMANPOWER MP where MP.RN = :NFCMANPOWER)');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and ((FM.BEGENG between :DDATE_FROM and :DDATE_TO) or (FM.ENDENG between :DDATE_FROM and :DDATE_TO) or');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' ((FM.BEGENG < :DDATE_FROM) and (COALESCE(FM.ENDENG, :DDATE_TO + 1) > :DDATE_TO)))');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and FM.RN = FMH.PRN');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and ((FMH.DO_ACT_FROM between :DDATE_FROM and :DDATE_TO) or (FMH.DO_ACT_TO between :DDATE_FROM and :DDATE_TO) or');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' ((FMH.DO_ACT_FROM < :DDATE_FROM) and (COALESCE(FMH.DO_ACT_TO, :DDATE_TO + 1) > :DDATE_TO)))');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and FMH.SCHEDULE = SH.RN');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and ' || PKG_SQL_BUILD.PKG_NAME(SNAME => 'PKG_P8PANELS_BASE.UTL_DOC_ACCESS_CHECK') ||'(FM.COMPANY, ' || PKG_SQL_BUILD.WRAP_STR(SVALUE => 'ClientPostPerform') || ', FM.RN) = 1');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' %ORDER_BY%) D) F');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' where F.NROW between :NROW_FROM and :NROW_TO');
/* Учтём сортировки */
PKG_P8PANELS_VISUAL.TDG_ORDERS_SET_QUERY(RDATA_GRID => RDG,
RORDERS => RO,
SPATTERN => '%ORDER_BY%',
CSQL => CSQL);
/* Разбираем его */
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 => 'NCOMPANY', NVALUE => NCOMPANY);
PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NINS_DEPARTMENT', NVALUE => RPRD.INS_DEPARTMENT);
PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NFCMANPOWER', NVALUE => RPRD.FCMANPOWER);
PKG_SQL_DML.BIND_VARIABLE_DATE(ICURSOR => ICURSOR, SNAME => 'DDATE_FROM', DVALUE => RPRD.DATE_FROM);
PKG_SQL_DML.BIND_VARIABLE_DATE(ICURSOR => ICURSOR, SNAME => 'DDATE_TO', DVALUE => RPRD.DATE_TO);
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_NUM(ICURSOR => ICURSOR, IPOSITION => 3);
PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 4);
/* Делаем выборку */
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 => 3, NVALUE => NPERS_LAB);
NPERS_LAB := F_DICMUNTS_BASE_RECALC_QUANT(NFLAG_SMART => 0,
NCOMPANY => NCOMPANY,
NUMEAS_FROM => NLAB_MEAS_HOURS,
NQUANT_FROM => NPERS_LAB,
NUMEAS_TO => RJB_PRMS.LAB_MEAS);
/* Накопим сумму в буфере результата */
NLAB_PLAN_FOT := NLAB_PLAN_FOT + NPERS_LAB;
/* При формировании списка для клиента */
if (NMODE = 0) then
/* Добавляем колонки с данными */
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NRN',
ICURSOR => ICURSOR,
NPOSITION => 1,
BCLEAR => true);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SPERSON',
ICURSOR => ICURSOR,
NPOSITION => 2);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NLAB_PLAN_FOT', NVALUE => NPERS_LAB);
/* Добавляем строку в таблицу */
PKG_P8PANELS_VISUAL.TDG_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
end if;
end loop;
/* Освобождаем курсор */
PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR);
exception
when others then
PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR);
raise;
end;
/* При формировании списка для клиента */
if (NMODE = 0) then
/* Сериализуем описание */
COUT := PKG_P8PANELS_VISUAL.TDG_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => NINCLUDE_DEF);
end if;
end JB_PERIODS_PLAN_FOT_BUILD;
/* Получение списка для детализации трудоёмкости по ФОТ периода балансировки */
procedure JB_PERIODS_PLAN_FOT_LIST
(
NJB_PERIODS in number, -- Рег. номер записи периода в буфере балансировки
NPAGE_NUMBER in number, -- Номер страницы (игнорируется при NPAGE_SIZE=0)
NPAGE_SIZE in number, -- Количество записей на странице (0 - все)
CORDERS in clob, -- Сортировки
NINCLUDE_DEF in number, -- Признак включения описания колонок таблицы в ответ
COUT out clob -- Сериализованная таблица данных
)
is
NTMP PKG_STD.TLNUMBER; -- Буфер для рассчетов
begin
/* Сформируем список детализации по ФОТ */
JB_PERIODS_PLAN_FOT_BUILD(NJB_PERIODS => NJB_PERIODS,
NMODE => 0,
NPAGE_NUMBER => NPAGE_NUMBER,
NPAGE_SIZE => NPAGE_SIZE,
CORDERS => CORDERS,
NINCLUDE_DEF => NINCLUDE_DEF,
NLAB_PLAN_FOT => NTMP,
COUT => COUT);
end JB_PERIODS_PLAN_FOT_LIST;
/* Расчет плановой трудоёмкости по ФОТ для периода балансировки (в часах) */
function JB_PERIODS_PLAN_FOT_CALC
(
NJB_PERIODS in number -- Рег. номер записи периода в буфере балансировки
) return number -- Плановая трудоёмкость по ФОТ (в часах)
is
NRES PKG_STD.TLNUMBER; -- Плановая трудоёмкость по ФОТ
CTMP clob; -- Буфер для вычислений
begin
/* Рассчитаем плановую трудоемкость по ФОТ */
JB_PERIODS_PLAN_FOT_BUILD(NJB_PERIODS => NJB_PERIODS, NMODE => 1, NLAB_PLAN_FOT => NRES, COUT => CTMP);
/* Вернём собранный результат */
return NRES;
end JB_PERIODS_PLAN_FOT_CALC;
/* Формирование и расчёт списка для детализации фактической трудоёмкости периода балансировки по "Планам и отчетам подразделений" */
procedure JB_PERIODS_FACT_RPT_BUILD
(
NJB_PERIODS in number, -- Рег. номер записи периода в буфере балансировки
NMODE in number := 0, -- Режим (0 - список для клиента, 1 - только расчёты)
NPAGE_NUMBER in number := 0, -- Номер страницы (игнорируется при NPAGE_SIZE=0 и NMODE = 1)
NPAGE_SIZE in number := 0, -- Количество записей на странице (0 - все, игнорируется при NMODE = 1)
CORDERS in clob := null, -- Сортировки (игнорируется при NMODE = 1)
NINCLUDE_DEF in number := 1, -- Признак включения описания колонок таблицы в ответ (игнорируется при NMODE = 1)
NLAB_FACT_RPT out number, -- Фактическая трудоёмкость согласно "Планам и отчетам подразделений"
COUT out clob -- Сериализованная таблица данных (заполняется только при NMODE = 0)
)
is
NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса
RPRD P8PNL_JB_PERIODS%rowtype; -- Запись детализируемого периода
RJB_PRMS P8PNL_JB_PRMS%rowtype; -- Параметры балансировки
RO PKG_P8PANELS_VISUAL.TDG_ORDERS; -- Сортировки
RDG PKG_P8PANELS_VISUAL.TDG; -- Описание таблицы
RDG_ROW PKG_P8PANELS_VISUAL.TDG_ROW; -- Строка таблицы
CSQL clob; -- Буфер для запроса
ICURSOR integer; -- Курсор для исполнения запроса
NROW_FROM PKG_STD.TREF; -- Номер строки с
NROW_TO PKG_STD.TREF; -- Номер строки по
DJOB_BEG PKG_STD.TLDATE; -- Дата начала текущей работы согласно проекту
DJOB_END PKG_STD.TLDATE; -- Дата окончания текущей работы согласно проекту
NJOB_DUR PKG_STD.TLNUMBER; -- Длительнось текущей работы согласно проекту
NJOB_LAB PKG_STD.TLNUMBER; -- Трудоёмкость текущей работы согласно отчету
NJOB_LAB_MEAS PKG_STD.TREF; -- ЕИ трудоемкости текущей работы согласно проекту
begin
/* Инициализируем сумму фактической трудоёмкости согласно "Планам и отчетам подразделений" */
NLAB_FACT_RPT := 0;
/* Считаем детализируемую запись периода */
RPRD := JB_PERIODS_GET(NJB_PERIODS => NJB_PERIODS);
/* Считаем параметры балансировки */
RJB_PRMS := JB_PRMS_GET(NIDENT => RPRD.IDENT);
/* Если не формируем данные для клиента */
if (NMODE = 1) then
/* Преобразуем номер и размер страницы в номер строк с и по - нам нужны все записи */
PKG_P8PANELS_VISUAL.UTL_ROWS_LIMITS_CALC(NPAGE_NUMBER => 0,
NPAGE_SIZE => 0,
NROW_FROM => NROW_FROM,
NROW_TO => NROW_TO);
else
/* Будем строить курсор по параметрам - читаем сортировки */
RO := PKG_P8PANELS_VISUAL.TDG_ORDERS_FROM_XML(CORDERS => CORDERS);
/* Преобразуем номер и размер страницы в номер строк с и по */
PKG_P8PANELS_VISUAL.UTL_ROWS_LIMITS_CALC(NPAGE_NUMBER => NPAGE_NUMBER,
NPAGE_SIZE => NPAGE_SIZE,
NROW_FROM => NROW_FROM,
NROW_TO => NROW_TO);
/* Инициализируем таблицу данных */
RDG := PKG_P8PANELS_VISUAL.TDG_MAKE();
/* Добавляем в таблицу описание колонок */
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NRN',
SCAPTION => 'Рег. номер трудового ресурса отчета',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SPRJDEPLAN',
SCAPTION => 'Документ',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BORDER => true);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SPRJ',
SCAPTION => 'Проект',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BORDER => true);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SSTG_JOB',
SCAPTION => 'Этап-работа',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BORDER => true);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SJOB_NAME',
SCAPTION => 'Наим. работы',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BORDER => true);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NJOB_STATE',
SCAPTION => 'Сост. работы',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BORDER => true);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'DJOB_BEG',
SCAPTION => 'Начало работы',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_DATE,
BORDER => true);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'DJOB_END',
SCAPTION => 'Окончание работы',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_DATE,
BORDER => true);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NJOB_DUR',
SCAPTION => 'Длительн. работы (' || RJB_PRMS.DURATION_MEAS_CODE || ')',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SPERSON',
SCAPTION => 'Сотрудник',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BORDER => true);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NLAB',
SCAPTION => 'Труд. (' || RJB_PRMS.LAB_MEAS_CODE || ')',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BORDER => true);
end if;
/* Обходим данные */
begin
/* Добавляем подсказку совместимости */
CSQL := PKG_SQL_BUILD.COMPATIBLE(SSQL => CSQL);
/* Обходим закрытые планы и отчеты подразеделений, подходящие по параметрам */
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => 'select *');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from (select D.*,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.SQLROWNUM() || ' NROW');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from (select MP.RN NRN,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' DT.DOCCODE || '', '' || trim(T.DOCPREF) || ''/'' || trim(T.DOCNUMB) || '', '' || TO_CHAR(T.DOCDATE, ''dd.mm.yyyy'') SPRJDEPLAN,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' P.CODE || ''-'' || P.NAME_USL SPRJ,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' trim(COALESCE(PS.NUMB, ''Б/Э'')) || ''-'' || trim(PJ.NUMB) SSTG_JOB,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' PJ.NAME SJOB_NAME,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' PJ.STATE NJOB_STATE,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' PJ.BEGPLAN DJOB_BEG,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' PJ.ENDPLAN DJOB_END,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' F_CLNPERSONS_FORMAT_CODE(FMP.COMPANY, FMP.CODE) SPERSON,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' MP.LABOUR_F NLAB,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' PJMP.UMEAS NLAB_MEAS');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from PRJDEPLAN T,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' DOCTYPES DT,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' ENPERIOD PR,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' PRJDEPLANMANPOW MP');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' left outer join CLNPSPFM FM on MP.CLNPSPFM = FM.RN');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' left outer join CLNPERSONS FMP on FM.PERSRN = FMP.RN,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' PROJECT P,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' PROJECTJOB PJ');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' left outer join PROJECTSTAGE PS on PJ.PROJECTSTAGE = PS.RN,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' PROJECTJOBMANPOW PJMP');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' where T.COMPANY = :NCOMPANY');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and T.STATE = 2');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and T.PERIOD = PR.RN');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and T.DOCTYPE = DT.RN');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and T.SUBDIV = :NINS_DEPARTMENT');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and ((PR.STARTDATE between :DDATE_FROM and :DDATE_TO) or (PR.ENDDATE between :DDATE_FROM and :DDATE_TO) or');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' ((PR.STARTDATE < :DDATE_FROM) and (PR.ENDDATE > :DDATE_TO)))');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and MP.PRN in (select PJ.RN from PRJDEPPLANJOB PJ where PJ.PRN = T.RN)');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and MP.PROJECTJOBMANPOW = PJMP.RN');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and PJMP.FCMANPOWER = :NFCMANPOWER');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and PJMP.PRN = PJ.RN');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and PJ.PRN = P.RN');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and exists (select null from V_USERPRIV UP where UP."CATALOG" = T.CRN)');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and exists (select null from V_USERPRIV UP where UP.JUR_PERS = T.JUR_PERS and UP.UNITCODE = ' || PKG_SQL_BUILD.WRAP_STR(SVALUE => 'ProjectDepartmentPlans') || ')');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' %ORDER_BY%) D) F');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' where F.NROW between :NROW_FROM and :NROW_TO');
/* Учтём сортировки */
PKG_P8PANELS_VISUAL.TDG_ORDERS_SET_QUERY(RDATA_GRID => RDG,
RORDERS => RO,
SPATTERN => '%ORDER_BY%',
CSQL => CSQL);
/* Разбираем его */
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 => 'NCOMPANY', NVALUE => NCOMPANY);
PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NINS_DEPARTMENT', NVALUE => RPRD.INS_DEPARTMENT);
PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NFCMANPOWER', NVALUE => RPRD.FCMANPOWER);
PKG_SQL_DML.BIND_VARIABLE_DATE(ICURSOR => ICURSOR, SNAME => 'DDATE_FROM', DVALUE => RPRD.DATE_FROM);
PKG_SQL_DML.BIND_VARIABLE_DATE(ICURSOR => ICURSOR, SNAME => 'DDATE_TO', DVALUE => RPRD.DATE_TO);
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_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_STR(ICURSOR => ICURSOR, IPOSITION => 9);
PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 10);
PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 11);
PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 12);
/* Делаем выборку */
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_DATE(ICURSOR => ICURSOR, IPOSITION => 7, DVALUE => DJOB_BEG);
PKG_SQL_DML.COLUMN_VALUE_DATE(ICURSOR => ICURSOR, IPOSITION => 8, DVALUE => DJOB_END);
P_PROJECTJOB_GET_DURATION(NCOMPANY => NCOMPANY,
DBEG_DATE => DJOB_BEG,
DEND_DATE => DJOB_END,
NDURATION_MEAS => RJB_PRMS.DURATION_MEAS,
NDURATION => NJOB_DUR);
/* Вычислим трудоёмкость работ в ЕИ панели */
PKG_SQL_DML.COLUMN_VALUE_NUM(ICURSOR => ICURSOR, IPOSITION => 10, NVALUE => NJOB_LAB);
PKG_SQL_DML.COLUMN_VALUE_NUM(ICURSOR => ICURSOR, IPOSITION => 11, NVALUE => NJOB_LAB_MEAS);
NJOB_LAB := F_DICMUNTS_BASE_RECALC_QUANT(NFLAG_SMART => 0,
NCOMPANY => NCOMPANY,
NUMEAS_FROM => NJOB_LAB_MEAS,
NQUANT_FROM => NJOB_LAB,
NUMEAS_TO => RJB_PRMS.LAB_MEAS);
/* Накопим сумму в буфере результата */
NLAB_FACT_RPT := NLAB_FACT_RPT + NJOB_LAB;
/* При формировании списка для клиента */
if (NMODE = 0) then
/* Добавляем колонки с данными */
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NRN',
ICURSOR => ICURSOR,
NPOSITION => 1,
BCLEAR => true);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SPRJDEPLAN',
ICURSOR => ICURSOR,
NPOSITION => 2);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SPRJ',
ICURSOR => ICURSOR,
NPOSITION => 3);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SSTG_JOB',
ICURSOR => ICURSOR,
NPOSITION => 4);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SJOB_NAME',
ICURSOR => ICURSOR,
NPOSITION => 5);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NJOB_STATE',
ICURSOR => ICURSOR,
NPOSITION => 6);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'DJOB_BEG', DVALUE => DJOB_BEG);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'DJOB_END', DVALUE => DJOB_END);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NJOB_DUR', NVALUE => NJOB_DUR);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SPERSON',
ICURSOR => ICURSOR,
NPOSITION => 9);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NLAB', NVALUE => NJOB_LAB);
/* Добавляем строку в таблицу */
PKG_P8PANELS_VISUAL.TDG_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
end if;
end loop;
/* Освобождаем курсор */
PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR);
exception
when others then
PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR);
raise;
end;
/* При формировании списка для клиента */
if (NMODE = 0) then
/* Сериализуем описание */
COUT := PKG_P8PANELS_VISUAL.TDG_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => NINCLUDE_DEF);
end if;
end JB_PERIODS_FACT_RPT_BUILD;
/* Получение списка для детализации фактической трудоёмкости периода балансировки по "Планам и отчетам подразделений" */
procedure JB_PERIODS_FACT_RPT_LIST
(
NJB_PERIODS in number, -- Рег. номер записи периода в буфере балансировки
NPAGE_NUMBER in number, -- Номер страницы (игнорируется при NPAGE_SIZE=0)
NPAGE_SIZE in number, -- Количество записей на странице (0 - все)
CORDERS in clob, -- Сортировки
NINCLUDE_DEF in number, -- Признак включения описания колонок таблицы в ответ
COUT out clob -- Сериализованная таблица данных
)
is
NTMP PKG_STD.TLNUMBER; -- Буфер для рассчетов
begin
/* Сформируем список детализации по "Планам и отчетам подразделений" */
JB_PERIODS_FACT_RPT_BUILD(NJB_PERIODS => NJB_PERIODS,
NMODE => 0,
NPAGE_NUMBER => NPAGE_NUMBER,
NPAGE_SIZE => NPAGE_SIZE,
CORDERS => CORDERS,
NINCLUDE_DEF => NINCLUDE_DEF,
NLAB_FACT_RPT => NTMP,
COUT => COUT);
end JB_PERIODS_FACT_RPT_LIST;
/* Расчёт фактической трудоёмкости трудового ресурса по "Планам и отчетам подразделеий" для периода балансировки */
function JB_PERIODS_FACT_RPT_CALC
(
NJB_PERIODS in number -- Рег. номер записи периода в буфере балансировки
) return number -- Фактическая трудоёмкость трудового ресурса по "Планам и отчетам подразделеий"
is
NRES PKG_STD.TLNUMBER; -- Буфер для результата
CTMP clob; -- Буфер для вычислений
begin
/* Рассчитаем фактическую трудоемкость по "Планам и отчетам подразделений" */
JB_PERIODS_FACT_RPT_BUILD(NJB_PERIODS => NJB_PERIODS, NMODE => 1, NLAB_FACT_RPT => NRES, COUT => CTMP);
/* Вернём собранный результат */
return NRES;
end JB_PERIODS_FACT_RPT_CALC;
/* Формирование и расчёт списка для детализации трудоёмкости периода балансировки по текущему состоянию графика */
procedure JB_PERIODS_PLAN_JOBS_BUILD
(
NJB_PERIODS in number, -- Рег. номер записи периода в буфере балансировки
NMODE in number := 0, -- Режим (0 - список для клиента, 1 - только расчёты)
NPAGE_NUMBER in number := 0, -- Номер страницы (игнорируется при NPAGE_SIZE=0 и NMODE = 1)
NPAGE_SIZE in number := 0, -- Количество записей на странице (0 - все, игнорируется при NMODE = 1)
CORDERS in clob := null, -- Сортировки (игнорируется при NMODE = 1)
NINCLUDE_DEF in number := 1, -- Признак включения описания колонок таблицы в ответ (игнорируется при NMODE = 1)
NLAB_PLAN_JOB out number, -- Плановая трудоёмкость согласно графика
COUT out clob -- Сериализованная таблица данных (заполняется только при NMODE = 0)
)
is
NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса
RPRD P8PNL_JB_PERIODS%rowtype; -- Запись детализируемого периода
RJB_PRMS P8PNL_JB_PRMS%rowtype; -- Параметры балансировки
RO PKG_P8PANELS_VISUAL.TDG_ORDERS; -- Сортировки
RDG PKG_P8PANELS_VISUAL.TDG; -- Описание таблицы
RDG_ROW PKG_P8PANELS_VISUAL.TDG_ROW; -- Строка таблицы
CSQL clob; -- Буфер для запроса
ICURSOR integer; -- Курсор для исполнения запроса
NROW_FROM PKG_STD.TREF; -- Номер строки с
NROW_TO PKG_STD.TREF; -- Номер строки по
DBEG PKG_STD.TLDATE; -- Дата начала для расчёта трудоёмкости текущей работы
DEND PKG_STD.TLDATE; -- Дата окончания для расчёта трудоёмкости текущей работы
DJOB_BEG PKG_STD.TLDATE; -- Дата начала текущей работы согласно плану-груфику
DJOB_END PKG_STD.TLDATE; -- Дата окончания текущей работы согласно плану-груфику
NJOB_DUR PKG_STD.TLNUMBER; -- Длительнось текущей работы согласно плану-груфику
NMP_LAB_MEAS PKG_STD.TREF; -- ЕИ трудоёмкости трудового ресурса согласно проекта
NMP_LAB PKG_STD.TLNUMBER; -- Трудоёмкость трудового ресурса в текущей работе согласно проекта
NMP_LAB_ONE PKG_STD.TLNUMBER; -- Трудоёмкость (за единицу длительности) трудового ресурса в текущей работе согласно проекта
NMP_LAB_PLAN PKG_STD.TLNUMBER; -- Трудоёмкость трудового ресурса в текущей работе согласно плана-графика
begin
/* Инициализируем сумму плановой трудоёмкости согласно графика */
NLAB_PLAN_JOB := 0;
/* Считаем детализируемую запись периода */
RPRD := JB_PERIODS_GET(NJB_PERIODS => NJB_PERIODS);
/* Считаем параметры балансировки */
RJB_PRMS := JB_PRMS_GET(NIDENT => RPRD.IDENT);
/* Если не формируем данные для клиента */
if (NMODE = 1) then
/* Преобразуем номер и размер страницы в номер строк с и по - нам нужны все записи */
PKG_P8PANELS_VISUAL.UTL_ROWS_LIMITS_CALC(NPAGE_NUMBER => 0,
NPAGE_SIZE => 0,
NROW_FROM => NROW_FROM,
NROW_TO => NROW_TO);
else
/* Будем строить курсор по параметрам - читаем сортировки */
RO := PKG_P8PANELS_VISUAL.TDG_ORDERS_FROM_XML(CORDERS => CORDERS);
/* Преобразуем номер и размер страницы в номер строк с и по */
PKG_P8PANELS_VISUAL.UTL_ROWS_LIMITS_CALC(NPAGE_NUMBER => NPAGE_NUMBER,
NPAGE_SIZE => NPAGE_SIZE,
NROW_FROM => NROW_FROM,
NROW_TO => NROW_TO);
/* Инициализируем таблицу данных */
RDG := PKG_P8PANELS_VISUAL.TDG_MAKE();
/* Добавляем в таблицу описание колонок */
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NRN',
SCAPTION => 'Рег. номер работы в буфере балансировки',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NPROJECT',
SCAPTION => 'Рег. номер проекта',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NJB_PRJCTS',
SCAPTION => 'Рег. номер буфера балансировки проекта',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SPRJ',
SCAPTION => 'Проект',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BORDER => true);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SSTG_JOB',
SCAPTION => 'Этап-работа',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BORDER => true);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SJOB_NAME',
SCAPTION => 'Наим. работы',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BORDER => true);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NJOB_STATE',
SCAPTION => 'Сост. работы',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BORDER => true);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'DJOB_BEG',
SCAPTION => 'Начало работы',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_DATE,
BORDER => true);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'DJOB_END',
SCAPTION => 'Окончание работы',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_DATE,
BORDER => true);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NJOB_DUR',
SCAPTION => 'Длительн. работы (' || RJB_PRMS.DURATION_MEAS_CODE || ')',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NMP_LAB',
SCAPTION => 'Труд. (' || RJB_PRMS.LAB_MEAS_CODE || ')',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NMP_LAB_ONE',
SCAPTION => 'Труд. (в ед. длит., ' || RJB_PRMS.LAB_MEAS_CODE || ')',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NMP_LAB_PLAN',
SCAPTION => 'Труд. (план, график, ' || RJB_PRMS.LAB_MEAS_CODE || ')',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB);
end if;
/* Обходим данные */
begin
/* Добавляем подсказку совместимости */
CSQL := PKG_SQL_BUILD.COMPATIBLE(SSQL => CSQL);
/* Формируем запрос */
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => 'select *');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from (select D.*,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.SQLROWNUM() || ' NROW');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from (select JB.RN NRN,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' P.RN NPROJECT,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' JBP.RN NJB_PRJCTS,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' P.CODE || ''-'' || P.NAME_USL SPRJ,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' trim(PS.NUMB) || ''-'' || trim(PJ.NUMB) SSTG_JOB,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' PJ.NAME SJOB_NAME,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' PJ.STATE NJOB_STATE,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' JB.DATE_FROM DJOB_BEG,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' JB.DATE_TO DJOB_END,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' PJMP.LABOUR_P NLABOUR_P,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' PJMP.UMEAS NLABOUR_P_UMEAS');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from P8PNL_JB_JOBS JB,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' P8PNL_JB_PRJCTS JBP,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' PROJECTJOB PJ');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' left outer join PROJECTSTAGE PS on PJ.PROJECTSTAGE = PS.RN,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' PROJECTJOBMANPOW PJMP,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' PROJECT P');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' where JB.IDENT = :NIDENT');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and JB.STAGE = ' || PKG_SQL_BUILD.WRAP_NUM(NVALUE => 0));
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and JB.PRN = JBP.RN');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and JB.SOURCE = PJ.RN');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and PJ.COMPANY = :NCOMPANY');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and PJ.PRN = P.RN');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and PJ.RN = PJMP.PRN');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and PJMP.FCMANPOWER = :NFCMANPOWER');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and PJMP.SUBDIV = :NINS_DEPARTMENT');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and ((JB.DATE_FROM between :DDATE_FROM and :DDATE_TO) or (JB.DATE_TO between :DDATE_FROM and :DDATE_TO) or');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' ((JB.DATE_FROM < :DDATE_FROM) and (JB.DATE_TO > :DDATE_TO)))');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and exists (select null from V_USERPRIV UP where UP."CATALOG" = P.CRN)');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and exists (select null from V_USERPRIV UP where UP.JUR_PERS = P.JUR_PERS and UP.UNITCODE = ' || PKG_SQL_BUILD.WRAP_STR(SVALUE => 'Projects') || ')');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' %ORDER_BY%) D) F');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' where F.NROW between :NROW_FROM and :NROW_TO');
/* Учтём сортировки */
PKG_P8PANELS_VISUAL.TDG_ORDERS_SET_QUERY(RDATA_GRID => RDG,
RORDERS => RO,
SPATTERN => '%ORDER_BY%',
CSQL => CSQL);
/* Разбираем его */
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 => 'NCOMPANY', NVALUE => NCOMPANY);
PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NIDENT', NVALUE => RPRD.IDENT);
PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NINS_DEPARTMENT', NVALUE => RPRD.INS_DEPARTMENT);
PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NFCMANPOWER', NVALUE => RPRD.FCMANPOWER);
PKG_SQL_DML.BIND_VARIABLE_DATE(ICURSOR => ICURSOR, SNAME => 'DDATE_FROM', DVALUE => RPRD.DATE_FROM);
PKG_SQL_DML.BIND_VARIABLE_DATE(ICURSOR => ICURSOR, SNAME => 'DDATE_TO', DVALUE => RPRD.DATE_TO);
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_NUM(ICURSOR => ICURSOR, IPOSITION => 2);
PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 3);
PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 4);
PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 5);
PKG_SQL_DML.DEFINE_COLUMN_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_DATE(ICURSOR => ICURSOR, IPOSITION => 9);
PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 10);
PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 11);
PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 12);
/* Делаем выборку */
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_DATE(ICURSOR => ICURSOR, IPOSITION => 8, DVALUE => DJOB_BEG);
PKG_SQL_DML.COLUMN_VALUE_DATE(ICURSOR => ICURSOR, IPOSITION => 9, DVALUE => DJOB_END);
PKG_SQL_DML.COLUMN_VALUE_NUM(ICURSOR => ICURSOR, IPOSITION => 10, NVALUE => NMP_LAB);
PKG_SQL_DML.COLUMN_VALUE_NUM(ICURSOR => ICURSOR, IPOSITION => 11, NVALUE => NMP_LAB_MEAS);
P_PROJECTJOB_GET_DURATION(NCOMPANY => NCOMPANY,
DBEG_DATE => DJOB_BEG,
DEND_DATE => DJOB_END,
NDURATION_MEAS => RJB_PRMS.DURATION_MEAS,
NDURATION => NJOB_DUR);
NMP_LAB := F_DICMUNTS_BASE_RECALC_QUANT(NFLAG_SMART => 0,
NCOMPANY => NCOMPANY,
NUMEAS_FROM => NMP_LAB_MEAS,
NQUANT_FROM => NMP_LAB,
NUMEAS_TO => RJB_PRMS.LAB_MEAS);
DBEG := RPRD.DATE_FROM;
if (DJOB_BEG > RPRD.DATE_FROM) then
DBEG := DJOB_BEG;
end if;
DEND := RPRD.DATE_TO;
if (DJOB_END < RPRD.DATE_TO) then
DEND := DJOB_END;
end if;
if (DJOB_END - DJOB_BEG <> 0) then
NMP_LAB_ONE := ROUND(NMP_LAB / (DJOB_END - DJOB_BEG), 3);
else
NMP_LAB_ONE := ROUND(NMP_LAB, 3);
end if;
NMP_LAB_PLAN := ROUND((DEND - DBEG) * NMP_LAB_ONE, 3);
/* Накопим сумму в буфере результата */
NLAB_PLAN_JOB := NLAB_PLAN_JOB + NMP_LAB_PLAN;
/* При формировании списка для клиента */
if (NMODE = 0) then
/* Добавляем колонки с данными */
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NRN',
ICURSOR => ICURSOR,
NPOSITION => 1,
BCLEAR => true);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NPROJECT',
ICURSOR => ICURSOR,
NPOSITION => 2);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NJB_PRJCTS',
ICURSOR => ICURSOR,
NPOSITION => 3);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SPRJ',
ICURSOR => ICURSOR,
NPOSITION => 4);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SSTG_JOB',
ICURSOR => ICURSOR,
NPOSITION => 5);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SJOB_NAME',
ICURSOR => ICURSOR,
NPOSITION => 6);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NJOB_STATE',
ICURSOR => ICURSOR,
NPOSITION => 7);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'DJOB_BEG', DVALUE => DJOB_BEG);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'DJOB_END', DVALUE => DJOB_END);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NJOB_DUR', NVALUE => NJOB_DUR);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NMP_LAB', NVALUE => NMP_LAB);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NMP_LAB_ONE', NVALUE => NMP_LAB_ONE);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NMP_LAB_PLAN', NVALUE => NMP_LAB_PLAN);
/* Добавляем строку в таблицу */
PKG_P8PANELS_VISUAL.TDG_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
end if;
end loop;
/* Освобождаем курсор */
PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR);
exception
when others then
PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR);
raise;
end;
/* При формировании списка для клиента */
if (NMODE = 0) then
/* Сериализуем описание */
COUT := PKG_P8PANELS_VISUAL.TDG_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => NINCLUDE_DEF);
end if;
end JB_PERIODS_PLAN_JOBS_BUILD;
/* Получение списка для детализации трудоёмкости периода балансировки по текущему состоянию графика */
procedure JB_PERIODS_PLAN_JOBS_LIST
(
NJB_PERIODS in number, -- Рег. номер записи периода в буфере балансировки
NPAGE_NUMBER in number, -- Номер страницы (игнорируется при NPAGE_SIZE=0)
NPAGE_SIZE in number, -- Количество записей на странице (0 - все)
CORDERS in clob, -- Сортировки
NINCLUDE_DEF in number, -- Признак включения описания колонок таблицы в ответ
COUT out clob -- Сериализованная таблица данных
)
is
NTMP PKG_STD.TLNUMBER; -- Буфер для рассчетов
begin
/* Сформируем список детализации по текущему состоянию плана-графика */
JB_PERIODS_PLAN_JOBS_BUILD(NJB_PERIODS => NJB_PERIODS,
NMODE => 0,
NPAGE_NUMBER => NPAGE_NUMBER,
NPAGE_SIZE => NPAGE_SIZE,
CORDERS => CORDERS,
NINCLUDE_DEF => NINCLUDE_DEF,
NLAB_PLAN_JOB => NTMP,
COUT => COUT);
end JB_PERIODS_PLAN_JOBS_LIST;
/* Расчёт плановой трудоёмкости по текущему состоянию графиков в буфере балансировки для периода балансировки */
function JB_PERIODS_PLAN_JOBS_CALC
(
NJB_PERIODS in number -- Рег. номер записи периода в буфере балансировки
) return number -- Плановая трудоёмкость по текущему состоянию графиков в буфере балансировки
is
NRES PKG_STD.TLNUMBER; -- Буфер для результата
CTMP clob; -- Буфер для вычислений
begin
/* Рассчитаем плановую трудоёмкость по текущему состоянию графиков */
JB_PERIODS_PLAN_JOBS_BUILD(NJB_PERIODS => NJB_PERIODS, NMODE => 1, NLAB_PLAN_JOB => NRES, COUT => CTMP);
/* Вернём результат */
return NRES;
end JB_PERIODS_PLAN_JOBS_CALC;
/* Установка трудоемкостей в записи периода балансировки работ */
procedure JB_PERIODS_SET_LAB
(
NJB_PERIODS in number, -- Рег. номер записи периода балансировки
NLAB_PLAN_FOT in number, -- Плановая трудоёмкость по ФОТ
NLAB_FACT_RPT in number, -- Фактическая трудоёмкость по "Планам и отчетам подразделений"
NLAB_PLAN_JOBS in number -- Плановая трудоёмкость по плану-графику
)
is
begin
/* Установим трудоёмкости */
update P8PNL_JB_PERIODS T
set T.LAB_PLAN_FOT = NLAB_PLAN_FOT,
T.LAB_FACT_RPT = NLAB_FACT_RPT,
T.LAB_PLAN_JOBS = NLAB_PLAN_JOBS
where T.RN = NJB_PERIODS;
end JB_PERIODS_SET_LAB;
/* Базовое добавление периода балансировки работ */
procedure JB_PERIODS_BASE_INSERT
(
NIDENT in number, -- Идентификатор процесса
DDATE_FROM in date, -- Начало
DDATE_TO in date, -- Окончание
NINS_DEPARTMENT in number, -- Рег. номер штатного подразделения
NFCMANPOWER in number, -- Рег. номер трудового ресурса
NLAB_PLAN_FOT in number := 0, -- Трудоёмкость (план, по ФОТ)
NLAB_FACT_RPT in number := 0, -- Трудоёмкость (факт, по отчёту)
NLAB_PLAN_JOBS in number := 0, -- Трудоёмкость (план, по графику)
NJB_PERIODS out number -- Рег. номер записи периода балансировки
)
is
begin
/* Сформируем рег. номер записи */
NJB_PERIODS := GEN_ID();
/* Добавим запись */
insert into P8PNL_JB_PERIODS
(RN,
IDENT,
DATE_FROM,
DATE_TO,
INS_DEPARTMENT,
FCMANPOWER,
LAB_PLAN_FOT,
LAB_FACT_RPT,
LAB_PLAN_JOBS)
values
(NJB_PERIODS,
NIDENT,
DDATE_FROM,
DDATE_TO,
NINS_DEPARTMENT,
NFCMANPOWER,
NLAB_PLAN_FOT,
NLAB_FACT_RPT,
NLAB_PLAN_JOBS);
end JB_PERIODS_BASE_INSERT;
/* Очистка периодов балансировки */
procedure JB_PERIODS_CLEAN
(
NIDENT in number -- Идентификатор процесса
)
is
begin
/* Удаляем периоды балансировки */
delete from P8PNL_JB_PERIODS T where T.IDENT = NIDENT;
end JB_PERIODS_CLEAN;
/* Пересчёт периодов балансировки */
procedure JB_PERIODS_RECALC
(
NIDENT in number, -- Идентификатор процесса
NINITIAL in number, -- Признак первоначального рассчёта (0 - пересчёт, 1 - первоначальный рассчёт)
NRESOURCE_STATUS out number -- Состояние ресурсов (0 - без отклонений, 1 - есть отклонения)
)
is
RJB_PRMS P8PNL_JB_PRMS%rowtype; -- Параметры балансировки
DJB_BEG PKG_STD.TLDATE; -- Дата начала периода балансировки
DJB_END PKG_STD.TLDATE; -- Дата окончания периода балансировки
DBEG PKG_STD.TLDATE; -- Дата начала текущего месяца периода балансировки
DEND PKG_STD.TLDATE; -- Дата окончания текущего месяца периода балансировки
NJB_PERIODS PKG_STD.TREF; -- Рег. номер добавленного периода балансировки
NLAB_PLAN_FOT PKG_STD.TLNUMBER; -- Плановая трудоёмкость по ФОТ для текущего месяца периода балансировки
NLAB_FACT_RPT PKG_STD.TLNUMBER; -- Фактическая трудоёмкость по "Планам и отчетам подразделений" для текущего месяца периода балансировки
NLAB_PLAN_JOBS PKG_STD.TLNUMBER; -- Плановая трудоёмкость по плану-графику в буфере для текущего месяца периода балансировки
begin
/* Считаем параметры балансировки */
RJB_PRMS := JB_PRMS_GET(NIDENT => NIDENT);
/* Подчистка при перерасчёте */
if (NINITIAL = 0) then
JB_PERIODS_CLEAN(NIDENT => NIDENT);
end if;
/* Скажем, что нет отклонений */
NRESOURCE_STATUS := 0;
/* Определим период балансировки */
DJB_BEG := RJB_PRMS.DATE_BEGIN;
DJB_END := JB_GET_END(NIDENT => NIDENT);
/* Сформируем записи периодов балансировки */
for I in 0 .. FLOOR(MONTHS_BETWEEN(DJB_END, DJB_BEG))
loop
DBEG := TRUNC(ADD_MONTHS(DJB_BEG, I), 'mm');
DEND := LAST_DAY(DBEG);
/* Определим подразделения, занятые в работах в этом месяце */
for D in (select JMP.FCMANPOWER,
JMP.SUBDIV
from P8PNL_JB_JOBS JB,
PROJECTJOB J,
PROJECTJOBMANPOW JMP
where JB.IDENT = NIDENT
and JB.STAGE = 0
and ((JB.DATE_FROM between DBEG and DEND) or (JB.DATE_TO between DBEG and DEND) or
((JB.DATE_FROM < DBEG) and (JB.DATE_TO > DEND)))
and JB.SOURCE = J.RN
and J.RN = JMP.PRN
and JMP.SUBDIV is not null
and exists (select null from V_USERPRIV UP where UP.CATALOG = J.CRN)
and exists (select null
from V_USERPRIV UP
where UP.JUR_PERS = J.JUR_PERS
and UP.UNITCODE = 'Projects')
and exists (select null
from UNITLIST UL
where UL.UNITCODE = 'INS_DEPARTMENT'
and UL.CHECK_ACCESS_HIER = 0
and exists (select /*+ INDEX(UP I_USERPRIV_COMPANY_ROLEID) */
null
from USERPRIV UP
where UP.COMPANY = JMP.COMPANY
and UP.UNITCODE = 'INS_DEPARTMENT'
and UP.ROLEID in (select /*+ INDEX(UR I_USERROLES_AUTHID_FK) */
UR.ROLEID
from USERROLES UR
where UR.AUTHID = UTILIZER)
union all
select /*+ INDEX(UP I_USERPRIV_COMPANY_AUTHID) */
null
from USERPRIV UP
where UP.COMPANY = JMP.COMPANY
and UP.UNITCODE = 'INS_DEPARTMENT'
and UP.AUTHID = UTILIZER)
union all
select /*+ INDEX(UP I_USERPRIV_HIERARCHY_ROLEID) */
null
from USERPRIV UP
where UP.HIERARCHY = JMP.SUBDIV
and UP.ROLEID in (select /*+ INDEX(UR I_USERROLES_AUTHID_FK) */
UR.ROLEID
from USERROLES UR
where UR.AUTHID = UTILIZER)
union all
select /*+ INDEX(UP I_USERPRIV_HIERARCHY_AUTHID) */
null
from USERPRIV UP
where UP.HIERARCHY = JMP.SUBDIV
and UP.AUTHID = UTILIZER)
group by JMP.FCMANPOWER,
JMP.SUBDIV)
loop
/* Добавим запись периода балансировки */
JB_PERIODS_BASE_INSERT(NIDENT => NIDENT,
DDATE_FROM => DBEG,
DDATE_TO => DEND,
NINS_DEPARTMENT => D.SUBDIV,
NFCMANPOWER => D.FCMANPOWER,
NLAB_PLAN_FOT => 0,
NLAB_FACT_RPT => 0,
NLAB_PLAN_JOBS => 0,
NJB_PERIODS => NJB_PERIODS);
/* Рассчитаем трудоёмкость по ФОТ (в часах) */
NLAB_PLAN_FOT := JB_PERIODS_PLAN_FOT_CALC(NJB_PERIODS => NJB_PERIODS);
/* Рассчитаем трудоемкость по "Планам и отчетам подразделений" */
NLAB_FACT_RPT := JB_PERIODS_FACT_RPT_CALC(NJB_PERIODS => NJB_PERIODS);
/* Рассчитаем трудоёмкость по работам графика */
NLAB_PLAN_JOBS := JB_PERIODS_PLAN_JOBS_CALC(NJB_PERIODS => NJB_PERIODS);
/* Сохраним расчёты */
JB_PERIODS_SET_LAB(NJB_PERIODS => NJB_PERIODS,
NLAB_PLAN_FOT => NLAB_PLAN_FOT,
NLAB_FACT_RPT => NLAB_FACT_RPT,
NLAB_PLAN_JOBS => NLAB_PLAN_JOBS);
/* Если плановая трудоёмкость по работам графика превысила ФОТ - значит с ресурсами всё плохо */
if (NLAB_PLAN_JOBS > NLAB_PLAN_FOT) then
NRESOURCE_STATUS := 1;
end if;
end loop;
end loop;
end JB_PERIODS_RECALC;
/* Список периодов балансировки */
procedure JB_PERIODS_LIST
(
NIDENT in number, -- Идентификатор процесса
NPAGE_NUMBER in number, -- Номер страницы (игнорируется при NPAGE_SIZE=0)
NPAGE_SIZE in number, -- Количество записей на странице (0 - все)
CORDERS in clob, -- Сортировки
NINCLUDE_DEF in number, -- Признак включения описания колонок таблицы в ответ
COUT out clob -- Сериализованная таблица данных
)
is
RJB_PRMS P8PNL_JB_PRMS%rowtype; -- Параметры балансировки
RO PKG_P8PANELS_VISUAL.TDG_ORDERS; -- Сортировки
RDG PKG_P8PANELS_VISUAL.TDG; -- Описание таблицы
RDG_ROW PKG_P8PANELS_VISUAL.TDG_ROW; -- Строка таблицы
CSQL clob; -- Буфер для запроса
ICURSOR integer; -- Курсор для исполнения запроса
NROW_FROM PKG_STD.TREF; -- Номер строки с
NROW_TO PKG_STD.TREF; -- Номер строки по
begin
/* Считаем параметры балансировки */
RJB_PRMS := JB_PRMS_GET(NIDENT => NIDENT);
/* Читаем сортировки */
RO := PKG_P8PANELS_VISUAL.TDG_ORDERS_FROM_XML(CORDERS => CORDERS);
/* Преобразуем номер и размер страницы в номер строк с и по */
PKG_P8PANELS_VISUAL.UTL_ROWS_LIMITS_CALC(NPAGE_NUMBER => NPAGE_NUMBER,
NPAGE_SIZE => NPAGE_SIZE,
NROW_FROM => NROW_FROM,
NROW_TO => NROW_TO);
/* Инициализируем таблицу данных */
RDG := PKG_P8PANELS_VISUAL.TDG_MAKE();
/* Добавляем в таблицу описание колонок */
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NRN',
SCAPTION => 'Рег. номер',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SPERIOD',
SCAPTION => 'Период',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BORDER => true,
BFILTER => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SINS_DEPARTMENT',
SCAPTION => 'Подразделение',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BORDER => true,
BFILTER => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SFCMANPOWER',
SCAPTION => 'Ресурс',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BORDER => true,
BFILTER => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NLAB_PLAN_FOT',
SCAPTION => 'Труд. (план, ФОТ, ' || RJB_PRMS.LAB_MEAS_CODE || ')',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BORDER => true,
BFILTER => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NLAB_FACT_RPT',
SCAPTION => 'Труд. (факт, отчёт, ' || RJB_PRMS.LAB_MEAS_CODE || ')',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => true,
BORDER => true,
BFILTER => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NLAB_DIFF_RPT_FOT',
SCAPTION => 'Отклон. (факт-план, ' || RJB_PRMS.LAB_MEAS_CODE || ')',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => true,
BORDER => true,
BFILTER => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NLAB_PLAN_JOBS',
SCAPTION => 'Труд. (план, график, ' || RJB_PRMS.LAB_MEAS_CODE || ')',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BORDER => true,
BFILTER => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NLAB_DIFF_JOBS_FOT',
SCAPTION => 'Отклон. (график-план, ' || RJB_PRMS.LAB_MEAS_CODE || ')',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BORDER => true,
BFILTER => false);
/* Обходим данные */
begin
/* Добавляем подсказку совместимости */
CSQL := PKG_SQL_BUILD.COMPATIBLE(SSQL => CSQL);
/* Формируем запрос */
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => 'select *');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from (select D.*,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.SQLROWNUM() || ' NROW');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from (select P.RN NRN,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' TO_CHAR(P.DATE_FROM, ''YYYY.MM'') SPERIOD,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' INSD.CODE SINS_DEPARTMENT,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' MP.CODE SFCMANPOWER,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' P.LAB_PLAN_FOT NLAB_PLAN_FOT,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' P.LAB_FACT_RPT NLAB_FACT_RPT,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' P.LAB_FACT_RPT - P.LAB_PLAN_FOT NLAB_DIFF_RPT_FOT,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' P.LAB_PLAN_JOBS NLAB_PLAN_JOBS,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' P.LAB_PLAN_JOBS - P.LAB_PLAN_FOT NLAB_DIFF_JOBS_FOT');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from P8PNL_JB_PERIODS P,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' INS_DEPARTMENT INSD,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' FCMANPOWER MP');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' where P.IDENT = :NIDENT');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and P.INS_DEPARTMENT = INSD.RN');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and P.FCMANPOWER = MP.RN');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and ' || PKG_SQL_BUILD.PKG_NAME(SNAME => 'PKG_P8PANELS_BASE.UTL_DOC_ACCESS_CHECK') ||'(INSD.COMPANY, ' || PKG_SQL_BUILD.WRAP_STR(SVALUE => 'INS_DEPARTMENT') || ', INSD.RN) = 1');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' %ORDER_BY%) D) F');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' where F.NROW between :NROW_FROM and :NROW_TO');
/* Учтём сортировки */
PKG_P8PANELS_VISUAL.TDG_ORDERS_SET_QUERY(RDATA_GRID => RDG,
RORDERS => RO,
SPATTERN => '%ORDER_BY%',
CSQL => CSQL);
/* Разбираем его */
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_STR(ICURSOR => ICURSOR, IPOSITION => 4);
PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 5);
PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 6);
PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 7);
PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 8);
PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 9);
PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 10);
/* Делаем выборку */
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.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NRN',
ICURSOR => ICURSOR,
NPOSITION => 1,
BCLEAR => true);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SPERIOD',
ICURSOR => ICURSOR,
NPOSITION => 2);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SINS_DEPARTMENT',
ICURSOR => ICURSOR,
NPOSITION => 3);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
SNAME => 'SFCMANPOWER',
ICURSOR => ICURSOR,
NPOSITION => 4);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NLAB_PLAN_FOT',
ICURSOR => ICURSOR,
NPOSITION => 5);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NLAB_FACT_RPT',
ICURSOR => ICURSOR,
NPOSITION => 6);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NLAB_DIFF_RPT_FOT',
ICURSOR => ICURSOR,
NPOSITION => 7);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NLAB_PLAN_JOBS',
ICURSOR => ICURSOR,
NPOSITION => 8);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
SNAME => 'NLAB_DIFF_JOBS_FOT',
ICURSOR => ICURSOR,
NPOSITION => 9);
/* Добавляем строку в таблицу */
PKG_P8PANELS_VISUAL.TDG_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
end loop;
/* Освобождаем курсор */
PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR);
exception
when others then
PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR);
raise;
end;
/* Сериализуем описание */
COUT := PKG_P8PANELS_VISUAL.TDG_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => NINCLUDE_DEF);
end JB_PERIODS_LIST;
/* Очистка данных балансировки */
procedure JB_CLEAN
(
NIDENT in number -- Идентификатор процесса
)
is
begin
/* Удаляем параметры балансировки */
JB_PRMS_CLEAN(NIDENT => NIDENT);
/* Удаляем список предшествующих работ */
delete from P8PNL_JB_JOBSPREV T where T.IDENT = NIDENT;
/* Удаляем список работ */
for C in (select T.RN
from P8PNL_JB_JOBS T
where T.IDENT = NIDENT
connect by prior T.RN = T.HRN
start with T.HRN is null
order by level desc)
loop
delete from P8PNL_JB_JOBS T where T.RN = C.RN;
end loop;
/* Удаляем список проектов */
delete from P8PNL_JB_PRJCTS T where T.IDENT = NIDENT;
/* Удаляем периоды балансировки */
JB_PERIODS_CLEAN(NIDENT => NIDENT);
end JB_CLEAN;
/* Перенос данных буфера балансировки в проекты */
procedure JB_SAVE
(
NIDENT in number, -- Идентификатор процесса
COUT out clob -- Список проектов
)
is
NJH PKG_STD.TREF; -- Рег. номер записи истории изменения работы
begin
/* Обходим изменённые проекты буфера */
for P in (select T.*
from P8PNL_JB_PRJCTS T
where T.IDENT = NIDENT
and T.CHANGED = 1)
loop
/* Обходим изменённые работы проекта */
for J in (select T.*
from P8PNL_JB_JOBS T
where T.IDENT = NIDENT
and T.PRN = P.RN
and T.STAGE = 0
and T.CHANGED = 1)
loop
/* Меняем работу в проекте */
for PJ in (select T.* from PROJECTJOB T where T.RN = J.SOURCE)
loop
P_PROJECTJOB_BASE_UPDATE(NRN => PJ.RN,
NCOMPANY => PJ.COMPANY,
NJUR_PERS => PJ.JUR_PERS,
NPROJECTSTAGE => PJ.PROJECTSTAGE,
NFACEACC => PJ.FACEACC,
SNUMB => PJ.NUMB,
SBUDG_NUMB => PJ.BUDG_NUMB,
SNAME => PJ.NAME,
NPRJOB => PJ.PRJOB,
NPRIORITY => PJ.PRIORITY,
NRESTRICTION => PJ.RESTRICTION,
DRESTRICT_DATE => PJ.RESTRICT_DATE,
NDURATION_CHG => PJ.DURATION_CHG,
NDURATION_NRM => PJ.DURATION_NRM,
NDURATION_MEAS => PJ.DURATION_MEAS,
NDURATION_P => PJ.DURATION_P,
NDURATION_F => PJ.DURATION_F,
NSUBDIV => PJ.SUBDIV,
NPERFORM => PJ.PERFORM,
NRELEASE => PJ.RELEASE,
NVOLUME_P => PJ.VOLUME_P,
NVOLUME_F => PJ.VOLUME_F,
NPRICE_P => PJ.PRICE_P,
NPRICE_F => PJ.PRICE_F,
NCURNAMES => PJ.CURNAMES,
NFPDARTCL => PJ.FPDARTCL,
NCOST_PLAN => PJ.COST_PLAN,
NCOST_FACT => PJ.COST_FACT,
NCOST_BPRICE => PJ.COST_BPRICE,
NCOST_CALC => PJ.COST_CALC,
NSTATE => PJ.STATE,
NPERFORM_PRC => PJ.PERFORM_PRC,
NFINDEFLINIT => PJ.FINDEFLINIT,
DBEGPLAN => J.DATE_FROM,
DBEGFACT => PJ.BEGFACT,
DENDPLAN => J.DATE_TO,
DENDFACT => PJ.ENDFACT,
SNOTE => PJ.NOTE,
DDO_ACT_FROM => sysdate,
NRFLCT_HS => PJ.RFLCT_HS,
NLAB_NORM => PJ.LAB_NORM,
NCALC_LAB => PJ.CALC_LAB,
NLAB_PLAN_I => PJ.LAB_PLAN,
NLAB_FACT_I => PJ.LAB_FACT,
NLAB_PART => PJ.LAB_PART,
NLAB_MEAS => PJ.LAB_MEAS,
SCHNG_BASE => PJ.CHNG_BASE,
NFACEACCPERF => PJ.FACEACCPERF,
NCHECK_DO_ACT_FROM => 0,
NLAB_UNITCOST => PJ.LAB_UNITCOST,
NLAB_CURRENCY => PJ.LAB_CURRENCY);
P_PROJECTJOBHS_MAKE_HIST(NCOMPANY => PJ.COMPANY, NPRN => PJ.RN, NCHECK_HS => 0, NRN => NJH);
end loop;
/* Снимаем флаг внесения изменений в буферную работу */
JB_JOBS_SET_CHANGED(NJB_JOBS => J.RN, NCHANGED => 0);
end loop;
/* Снимаем флаг внесения изменений в буферный проект */
JB_PRJCTS_SET_CHANGED(NJB_PRJCTS => P.RN, NCHANGED => 0);
end loop;
/* Вернём пересобранный список проектов */
JB_PRJCTS_LIST(NIDENT => NIDENT, COUT => COUT);
end JB_SAVE;
/* Формирование исходных данных для балансировки планов-графиков работ */
procedure JB_INIT
(
DBEGIN in out date, -- Дата начала периода мониторинга загрузки ресурсов
DFACT in out date, -- Факт по состоянию на
NDURATION_MEAS out number, -- Единица измерения длительности (0 - день, 1 - неделя, 2 - декада, 3 - месяц, 4 - квартал, 5 - год)
SDURATION_MEAS out varchar2, -- Единица измерения длительности (мнемокод)
NLAB_MEAS out number, -- Единица измерения трудоёмкости
SLAB_MEAS out varchar2, -- Единица измерения трудоёмкости (мнемокод)
NIDENT in out number, -- Идентификатор процесса (null - сгенерировать новый, !null - удалить старые данные и пересоздать с указанным идентификатором)
NRESOURCE_STATUS out number -- Состояние ресурсов (0 - без отклонений, 1 - есть отклонения)
)
is
NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса
SUTILIZER PKG_STD.TSTRING := UTILIZER(); -- Пользователь сеанса
NJB_PRJCTS PKG_STD.TREF; -- Рег. номер проекта в списке для балансировки
NJB_JOBS_STAGE PKG_STD.TREF; -- Рег. номер этапа проекта в списке для балансировки
NJB_JOBS_JOB PKG_STD.TREF; -- Рег. номер работы проекта в списке для балансировки
NJB_JOBS_JOBPREV PKG_STD.TREF; -- Рег. номер предшествующей работы проекта в списке для балансировки
RH_JB_JOBS P8PNL_JB_JOBS%rowtype; -- Запись родительской работы/этапа в иехархии балансируемых
RH_JB_JOBS_PREV P8PNL_JB_JOBS%rowtype; -- Запись предшествующей работы в иехархии балансируемых
NDURATION P8PNL_JB_JOBS.DURATION%type; -- Длительност текущей работы/этапа
NEDITABLE PKG_STD.TREF; -- Признак возможности редактирования работы
NPRMS PKG_STD.TREF; -- Рег. номер записи параметров балансировки
begin
/* Обработаем дату начала периода мониторинга загрузки ресурсов */
if (DBEGIN is null) then
DBEGIN := TRUNC(sysdate, 'yyyy');
else
DBEGIN := TRUNC(DBEGIN, 'mm');
end if;
/* Обработаем дату факта */
if (DFACT is null) then
select LAST_DAY(TRUNC(COALESCE(max(ENP.ENDDATE), DBEGIN), 'mm'))
into DFACT
from PRJDEPLAN T,
ENPERIOD ENP
where T.COMPANY = NCOMPANY
and T.STATE = 2
and T.PERIOD = ENP.RN
and exists (select null from V_USERPRIV UP where UP.CATALOG = T.CRN)
and exists (select null
from V_USERPRIV UP
where UP.JUR_PERS = T.JUR_PERS
and UP.UNITCODE = 'ProjectDepartmentPlans');
else
DFACT := LAST_DAY(TRUNC(DFACT, 'mm'));
end if;
/* Обработаем единицу измерения длительности (пока - она всегда должна быть "день", по умолчанию) */
NDURATION_MEAS := NJB_DURATION_MEAS;
SDURATION_MEAS := JB_GET_DURATION_MEAS_CODE(NDURATION_MEAS => NDURATION_MEAS);
/* Обработаем единицу измерения трудоёмкости (пока - она всегда должна быть "ч/ч", по умолчанию) */
SLAB_MEAS := SJB_LAB_MEAS;
FIND_DICMUNTS_BY_MNEMO(NFLAG_SMART => 0, NCOMPANY => NCOMPANY, SMEAS_MNEMO => SLAB_MEAS, NRN => NLAB_MEAS);
/* Отработаем идентификатор процесса */
if (NIDENT is null) then
NIDENT := GEN_IDENT();
else
JB_CLEAN(NIDENT => NIDENT);
end if;
/* Сохраняем параметры балансировки */
JB_PRMS_BASE_INSERT(NIDENT => NIDENT,
DDATE_BEGIN => DBEGIN,
DDATE_FACT => DFACT,
NDURATION_MEAS => NDURATION_MEAS,
SDURATION_MEAS_CODE => SDURATION_MEAS,
NLAB_MEAS => NLAB_MEAS,
SLAB_MEAS_CODE => SLAB_MEAS,
NRN => NPRMS);
/* Обходим проекты */
for PRJ in (select P.RN NRN,
COALESCE((select 1
from PROJECTJOB PJ,
PROJECTSTAGE PS
where PJ.PRN = P.RN
and PJ.BEGPLAN is not null
and PJ.ENDPLAN is not null
and PJ.PROJECTSTAGE = PS.RN
and PS.BEGPLAN is not null
and PS.ENDPLAN is not null
and ROWNUM <= 1),
0) NJOBS,
0 NEDITABLE,
P.BEGPLAN DBEGPLAN,
P.ENDPLAN DENDPLAN
from PROJECT P
where P.COMPANY = NCOMPANY
and P.STATE not in (3, 5)
and exists (select null from V_USERPRIV UP where UP.CATALOG = P.CRN)
and exists (select null
from V_USERPRIV UP
where UP.JUR_PERS = P.JUR_PERS
and UP.UNITCODE = 'Projects')
order by P.NAME_USL)
loop
/* Установим признак доступности редактирования */
if (CHECK_RESPONSIBLE(NRN => PRJ.NRN, SAUTHID => SUTILIZER) = 1) then
PRJ.NEDITABLE := 1;
end if;
/* Помещаем проект в список балансируемых */
JB_PRJCTS_BASE_INSERT(NIDENT => NIDENT,
NPROJECT => PRJ.NRN,
NJOBS => PRJ.NJOBS,
NEDITABLE => PRJ.NEDITABLE,
NCHANGED => 0,
NJB_PRJCTS => NJB_PRJCTS);
/* Обходим этапы проекта в порядке иерархии */
for STG in (select PS.COMPANY NCOMPANY,
PS.RN NRN,
PS.HRN NHRN,
trim(PS.NUMB) SNUMB,
PS.NAME SNAME,
PS.BEGPLAN DBEGPLAN,
PS.ENDPLAN DENDPLAN,
COALESCE(AG.AGNABBR, DP.CODE) SEXECUTOR
from PROJECTSTAGE PS,
AGNLIST AG,
INS_DEPARTMENT DP
where PS.PRN = PRJ.NRN
and PS.BEGPLAN is not null
and PS.ENDPLAN is not null
and PS.RESPONSIBLE = AG.RN(+)
and PS.SUBDIV_RESP = DP.RN(+)
connect by prior PS.RN = PS.HRN
start with PS.HRN is null
order by level,
PS.NUMB,
PS.BEGPLAN)
loop
/* Найдём родительский этап в списке балансировки */
if (STG.NHRN is not null) then
RH_JB_JOBS := JB_JOBS_GET_BY_SOURCE(NIDENT => NIDENT, NPRN => NJB_PRJCTS, NSOURCE => STG.NHRN);
else
RH_JB_JOBS := null;
end if;
/* Определим длительность этапа */
P_PROJECTJOB_GET_DURATION(NCOMPANY => STG.NCOMPANY,
DBEG_DATE => STG.DBEGPLAN,
DEND_DATE => STG.DENDPLAN,
NDURATION_MEAS => NDURATION_MEAS,
NDURATION => NDURATION);
/* Помещаем этап в список балансировки */
JB_JOBS_BASE_INSERT(NIDENT => NIDENT,
NPRN => NJB_PRJCTS,
NHRN => RH_JB_JOBS.RN,
NSOURCE => STG.NRN,
SNUMB => STG.SNUMB,
SNAME => STG.SNAME,
DDATE_FROM => STG.DBEGPLAN,
DDATE_TO => STG.DENDPLAN,
NDURATION => COALESCE(NDURATION, 0),
SEXECUTOR => STG.SEXECUTOR,
NSTAGE => 1,
NEDITABLE => 0,
NJB_JOBS => NJB_JOBS_STAGE);
/* Обходим работы этапа */
for PJ in (select J.COMPANY NCOMPANY,
J.RN NRN,
trim(J.NUMB) SNUMB,
J.NAME SNAME,
J.BEGPLAN DBEGPLAN,
J.ENDPLAN DENDPLAN,
COALESCE(COALESCE(DP.CODE, AG.AGNABBR), STG.SEXECUTOR) SEXECUTOR,
J.STATE NSTATE,
J.DURATION_CHG NDURATION_CHG
from PROJECTJOB J,
AGNLIST AG,
INS_DEPARTMENT DP
where J.PRN = PRJ.NRN
and J.PROJECTSTAGE = STG.NRN
and J.BEGPLAN is not null
and J.ENDPLAN is not null
and J.SUBDIV = DP.RN(+)
and J.PERFORM = AG.RN(+)
order by J.NUMB,
J.BEGPLAN)
loop
/* Определим возможность редактирования работы */
NEDITABLE := 1;
if ((PRJ.NEDITABLE = 0) or (PJ.NSTATE <> 0) or (PJ.NDURATION_CHG <> 2)) then
NEDITABLE := 0;
end if;
/* Определим длительность работы */
P_PROJECTJOB_GET_DURATION(NCOMPANY => PJ.NCOMPANY,
DBEG_DATE => PJ.DBEGPLAN,
DEND_DATE => PJ.DENDPLAN,
NDURATION_MEAS => NDURATION_MEAS,
NDURATION => NDURATION);
/* Помещаем работу в список балансировки */
JB_JOBS_BASE_INSERT(NIDENT => NIDENT,
NPRN => NJB_PRJCTS,
NHRN => NJB_JOBS_STAGE,
NSOURCE => PJ.NRN,
SNUMB => PJ.SNUMB,
SNAME => PJ.SNAME,
DDATE_FROM => PJ.DBEGPLAN,
DDATE_TO => PJ.DENDPLAN,
NDURATION => COALESCE(NDURATION, 0),
SEXECUTOR => PJ.SEXECUTOR,
NSTAGE => 0,
NEDITABLE => NEDITABLE,
NJB_JOBS => NJB_JOBS_JOB);
end loop;
end loop;
/* Обходим работы проекта ещё раз, для наполнения списка предшествующих в буфере балансировки */
for PJ in (select J.RN NRN
from PROJECTJOB J
where J.PRN = PRJ.NRN
and exists (select null
from P8PNL_JB_JOBS JB
where JB.IDENT = NIDENT
and JB.STAGE = 0
and JB.SOURCE = J.RN))
loop
RH_JB_JOBS := JB_JOBS_GET_BY_SOURCE(NIDENT => NIDENT, NPRN => NJB_PRJCTS, NSOURCE => PJ.NRN);
/* Помещаем предшествующие работы в буфер балансировки */
for PJPREV in (select JP.PROJECTJOB NPROJECTJOB from PROJECTJOBPREV JP where JP.PRN = PJ.NRN)
loop
RH_JB_JOBS_PREV := JB_JOBS_GET_BY_SOURCE(NIDENT => NIDENT, NPRN => NJB_PRJCTS, NSOURCE => PJPREV.NPROJECTJOB);
JB_JOBSPREV_BASE_INSERT(NIDENT => NIDENT,
NPRN => RH_JB_JOBS.RN,
NJB_JOBS => RH_JB_JOBS_PREV.RN,
NJB_JOBSPREV => NJB_JOBS_JOBPREV);
end loop;
end loop;
end loop;
/* Сформируем данные монитора загрузки ресурсов */
JB_PERIODS_RECALC(NIDENT => NIDENT, NINITIAL => 1, NRESOURCE_STATUS => NRESOURCE_STATUS);
end JB_INIT;
/* Формирование подсказки для колонки "Статус структуры цены" */
function INFO_COST_STATUS_HINT
(
NTYPE in number -- Тип подсказки (0 - для статьи, 1 - для проекта/этапа)
) return varchar2 -- Подсказка
is
SICON_STYLE PKG_STD.TSTRING; -- Стиль иконки
SICON PKG_STD.TSTRING; -- Иконка
begin
SICON_STYLE := 'font-family: ''Material Icons''; font-size: 0.8em;';
SICON := '<span style="' || SICON_STYLE || '">circle</span>';
if (NTYPE = 0) then
return 'Контроль фактических затрат:<br>' ||
'<b style="color:red">' || SICON || ' Перерасход</b> - фактические затраты превышают плановые<br>' ||
'<b style="color:orange">' || SICON || ' Расход более 90%</b> - фактические затраты составляют 90% (и более) от плановых<br>' ||
'<b style="color:green">' || SICON || ' Без отклонений</b> - фактические затраты менее 90% от плановых<br>' ||
'<b style="color:lightgray">' || SICON || ' Не определено</b> - контроль затрат по статье не проводится';
else
return 'Контроль фактических затрат в разрезе статей структуры цены:<br>' ||
'<b style="color:red">' || SICON || ' Есть статьи с перерасходом</b> - в составе структуры цены проекта/этапа есть статьи, фактические затраты по которым превышают плановые<br>' ||
'<b style="color:orange">' || SICON || ' Есть статьи с расходом более 90%</b> - в составе структуры цены проекта/этапа есть статьи, фактические затраты по которым составляют 90% (и более) от плановых<br>' ||
'<b style="color:green">' || SICON || ' Без отклонений</b> - в составе структуры цены проекта/этапа все статьи, имеют объем фактических затраты менее 90% от плановых<br>' ||
'<b style="color:lightgray">' || SICON || ' Не определено</b> - в составе структуры цены проекта/этапа нет статей, по которым ведется контроль затрат';
end if;
end INFO_COST_STATUS_HINT;
/* Формирование подсказки для колонки "Готов (%, затраты)" */
function INFO_COST_READY_HINT
return varchar2 -- Подсказка
is
begin
return 'Процент готовности по затратам расчитывается как отношение плановой себестоимости проекта/этапа (по структуре цены) к фактической, зафиксированной на данный момент в разделе "Журнал затрат". Цветом выделены диапазоны:<br>' ||
'<b style="color:red">30% и менее</b> - низкая степень готовности<br>' ||
'<b style="color:orange">От 31% до 79%</b> - средняя степень готовности<br>' ||
'<b style="color:green">80% и более</b> - высокая степень готовности<br>';
end INFO_COST_READY_HINT;
/* Формирование подсказки для колонки "Состояние" */
function INFO_STATE_HINT
return varchar2 -- Подсказка
is
SCONT_STYLE PKG_STD.TSTRING; -- Стиль контейнера
SICON_STYLE PKG_STD.TSTRING; -- Стиль иконки
begin
SCONT_STYLE := 'display: flex; align-items: center;';
SICON_STYLE := 'font-family: ''Material Icons''; font-size: 1.5em;';
return '<span style="' || SCONT_STYLE || '"><span style="' || SICON_STYLE || '">app_registration</span> - Зарегистрирован</span>' ||
'<span style="' || SCONT_STYLE || '"><span style="' || SICON_STYLE || '">lock_open</span> - Открыт</span>' ||
'<span style="' || SCONT_STYLE || '"><span style="' || SICON_STYLE || '">do_not_disturb_on</span> - Остановлен</span>' ||
'<span style="' || SCONT_STYLE || '"><span style="' || SICON_STYLE || '">lock_outline</span> - Закрыт</span>' ||
'<span style="' || SCONT_STYLE || '"><span style="' || SICON_STYLE || '">thumb_up_alt</span> - Согласован</span>' ||
'<span style="' || SCONT_STYLE || '"><span style="' || SICON_STYLE || '">block</span> - Исполнение прекращено</span>';
end INFO_STATE_HINT;
/* Получение состояния структуры цены проекта/этапа проекта */
function INFO_COST_STATUS_GET
(
NPROJECT in number, -- Рег. номер проекта
NPROJECTSTAGE in number := null -- Рег. номер этапа (null - по всем)
) return number -- Состояние структуры цены (-1 - не определено, 0 - без отклонений, 1 - есть статьи с расходом больше 90%, 2 - есть статьи с перерасходом)
is
RINFO_STAGE_ARTS TINFO_STAGE_ARTS; -- Список статей структуры цены
NRES PKG_STD.TNUMBER := -1; -- Состояние структуры цены
begin
/* Обходим этапы проекта */
for C in (select PS.RN
from PROJECTSTAGE PS
where PS.PRN = NPROJECT
and ((NPROJECTSTAGE is null) or ((NPROJECTSTAGE is not null) and (PS.RN = NPROJECTSTAGE))))
loop
/* Сформируем список статей структуры цены */
INFO_STAGE_ARTS_GET(NPROJECTSTAGE => C.RN, RINFO_STAGE_ARTS => RINFO_STAGE_ARTS);
/* Обходим собранные статьи */
if ((RINFO_STAGE_ARTS is not null) and (RINFO_STAGE_ARTS.COUNT > 0)) then
for I in RINFO_STAGE_ARTS.FIRST .. RINFO_STAGE_ARTS.LAST
loop
/* Чем хуже (выше) отклонение статьи - тем выше оно у этапа/проекта */
if (RINFO_STAGE_ARTS(I).NCOST_STATUS > NRES) then
NRES := RINFO_STAGE_ARTS(I).NCOST_STATUS;
end if;
/* Если мы уже добрались до самого худшего отклонения - дальше можно не смотреть */
if (NRES = 2) then
return NRES;
end if;
end loop;
end if;
end loop;
/* Возвращаем полученное состояние */
return NRES;
end INFO_COST_STATUS_GET;
/* Получение % готовности проекта/этапа проекта (по затратам) */
function INFO_COST_READY_GET
(
NPROJECT in number, -- Рег. номер проекта
NPROJECTSTAGE in number := null -- Рег. номер этапа (null - по всем)
) return number -- % готовности
is
RINFO_STAGE_ARTS TINFO_STAGE_ARTS; -- Список статей структуры цены
NCOST_FACT PKG_STD.TLNUMBER := 0; -- Сумма фактических затрат по проекту
NCOST_PLAN PKG_STD.TLNUMBER := 0; -- Сумма плановых затрат по проекту
NRES PKG_STD.TNUMBER := 0; -- Буфер для результата
begin
/* Обходим этапы проекта */
for C in (select PS.RN
from PROJECTSTAGE PS
where PS.PRN = NPROJECT
and ((NPROJECTSTAGE is null) or ((NPROJECTSTAGE is not null) and (PS.RN = NPROJECTSTAGE))))
loop
/* Сформируем список статей структуры цены этапа */
INFO_STAGE_ARTS_GET(NPROJECTSTAGE => C.RN, RINFO_STAGE_ARTS => RINFO_STAGE_ARTS);
/* Обходим собранные статьи */
if ((RINFO_STAGE_ARTS is not null) and (RINFO_STAGE_ARTS.COUNT > 0)) then
for I in RINFO_STAGE_ARTS.FIRST .. RINFO_STAGE_ARTS.LAST
loop
/* Суммируем затраты по статьям, подлежащим котролю затрат */
if (RINFO_STAGE_ARTS(I).NCOST_CTL) then
NCOST_PLAN := NCOST_PLAN + RINFO_STAGE_ARTS(I).NPLAN_SUM;
NCOST_FACT := NCOST_FACT + RINFO_STAGE_ARTS(I).NFACT_SUM;
end if;
end loop;
end if;
end loop;
/* Если есть и фактические затраты и плановая себестоимость */
if ((NCOST_FACT > 0) and (NCOST_PLAN > 0)) then
/* Отношение фактических затрат к плановым - искомый % готовности */
NRES := ROUND(NCOST_FACT / NCOST_PLAN * 100, 0);
/* Если фактические затраты превысили плановые, то % может быть > 100, но это бессмысленно в данном показателе - откорректируем ситуацию */
if (NRES > 100) then
NRES := 100;
end if;
end if;
/* Вернём рассчитанное */
return NRES;
end INFO_COST_READY_GET;
/* Подбор записей журнала затрат (факт) */
procedure INFO_FCCOSTNOTES_FACT_SELECT
(
NFACEACC in number, -- Рег. номер лицевого счета
NFPDARTCL in number, -- Рег. номер статьи затрат
NIDENT out number -- Идентификатор буфера подобранных (списка отмеченных записей, null - не найдено)
)
is
NSELECTLIST PKG_STD.TREF; -- Рег. номер добавленной записи буфера подобранных
begin
/* Подберём записи журнала затрат */
for C in (select CN.COMPANY,
CN.RN
from FCCOSTNOTES CN,
FINSTATE FS
where CN.PROD_ORDER = NFACEACC
and CN.COST_ARTICLE = NFPDARTCL
and CN.COST_TYPE = FS.RN
and FS.TYPE = 1
and exists (select null from V_USERPRIV UP where UP.CATALOG = CN.CRN))
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 INFO_FCCOSTNOTES_FACT_SELECT;
/* Расчет суммы фактических затрат по журналу затрат */
function INFO_FCCOSTNOTES_FACT_GET
(
NFACEACC in number, -- Рег. номер лицевого счета
NFPDARTCL in number -- Рег. номер статьи затрат
) return number -- Сумма-факт по статье
is
NRES PKG_STD.TNUMBER; -- Буфер для рузультата
begin
/* Суммируем факт по лицевому счёту затрат этапа и указанной статье */
select COALESCE(sum(CN.COST_BSUM), 0)
into NRES
from FCCOSTNOTES CN,
FINSTATE FS
where CN.PROD_ORDER = NFACEACC
and CN.COST_ARTICLE = NFPDARTCL
and CN.COST_TYPE = FS.RN
and FS.TYPE = 1;
/* Возвращаем результат */
return NRES;
end INFO_FCCOSTNOTES_FACT_GET;
/* Поиск активной структуры цены (утвеждена или согласована, актуальна по датам, активна) */
function INFO_CONTRPRSTRUCT_ACTIVE_FIND
(
NPROJECTSTAGE in number -- Рег. номер этапа проекта
) return number -- Рег. номер записи структуры цены
is
begin
/* Подбираем актуальную по дате, активную, утверждённую или согласованную */
for C in (select CSP.RN
from PROJECTSTAGE PS,
STAGES CS,
CONTRPRSTRUCT CSP
where PS.RN = NPROJECTSTAGE
and PS.FACEACCCUST = CS.FACEACC
and CS.RN = CSP.PRN
and CSP.SIGN_ACT = 1
and CSP.STATE in (1, 2)
and ((CSP.DATE_FROM is null) or ((CSP.DATE_FROM is not null) and (CSP.DATE_FROM <= sysdate)))
and ((CSP.DATE_TO is null) or ((CSP.DATE_TO is not null) and (CSP.DATE_TO >= sysdate)))
order by CSP.DATE_TO desc)
loop
/* Возвращаем первую */
return C.RN;
end loop;
/* Ничего не нашли */
return null;
end INFO_CONTRPRSTRUCT_ACTIVE_FIND;
/* Получение флага необходимости контроля затрат по статье */
function INFO_FPDARTCL_COST_IS_CTL
(
NRN in number -- Рег. номер статьи затрат
) return boolean -- Признак необходимости контроля затрат
is
NCOMPANY PKG_STD.TREF; -- Рег. номер организации
NCTL_COST_DP PKG_STD.TREF; -- Рег. номер доп. свойства, определяющего необходимость контроля затрат по статье
begin
/* Обратимся к статье затрат */
for C in (select T.VERSION,
T.RN
from FPDARTCL T
where T.RN = NRN)
loop
/* Определим организацию */
FIND_COMPANY_BY_VERSION(NVERSION => C.VERSION, SUNITCODE => 'FinPlanArticles', NCOMPANY => NCOMPANY);
/* Определим дополнительные свойства - необходимость контроля затрат */
FIND_DOCS_PROPS_CODE(NFLAG_SMART => 1, NCOMPANY => NCOMPANY, SCODE => SDP_SCTL_COST, NRN => NCTL_COST_DP);
/* Для статей, подлежащих контролю затрат */
if (UPPER(F_DOCS_PROPS_GET_STR_VALUE(NPROPERTY => NCTL_COST_DP, SUNITCODE => 'FinPlanArticles', NDOCUMENT => C.RN)) =
UPPER(SYES)) then
return true;
end if;
end loop;
/* Нет статьи (ну или мы раньше не вышли) - нет контроля */
return false;
end INFO_FPDARTCL_COST_IS_CTL;
/* Список проектов (таблица данных) */
procedure INFO_PROJECTS_DG
(
SPRJ_TYPE in varchar2 := null, -- Мнемокод типа проекта
SINS_DEPARTMENT in varchar2 := null, -- Мнемокод штатного подразделения
NCOST_STATUS in number := 0, -- Статус структуры цены (0 - все, 1 - есть статьи с расходом больше 90%, 2 - есть статьи с перерасходом)
NSTATE in number := 0, -- Состояние (0 - все, 1 - открытые, 2 - неоткрытые, т.е. с прочими статусами)
SSEARCH in varchar2 := null, -- Строка поиска
NPAGE_NUMBER in number, -- Номер страницы (игнорируется при NPAGE_SIZE=0)
NPAGE_SIZE in number, -- Количество записей на странице (0 - все)
CORDERS in clob, -- Сортировки
NINCLUDE_DEF in number, -- Признак включения описания колонок таблицы в ответ
COUT out clob -- Сериализованная таблица данных
)
is
NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса
RO PKG_P8PANELS_VISUAL.TDG_ORDERS; -- Сортировки
RDG PKG_P8PANELS_VISUAL.TDG; -- Описание таблицы
RDG_ROW PKG_P8PANELS_VISUAL.TDG_ROW; -- Строка таблицы
NROW_FROM PKG_STD.TREF; -- Номер строки с
NROW_TO PKG_STD.TREF; -- Номер строки по
SSEARCH_PREPARED PKG_STD.TSTRING; -- Подготовленная для использования в запросе поисковая строка
CSQL clob; -- Буфер для запроса
ICURSOR integer; -- Курсор для исполнения запроса
begin
/* Читаем сортировки */
RO := PKG_P8PANELS_VISUAL.TDG_ORDERS_FROM_XML(CORDERS => CORDERS);
/* Преобразуем номер и размер страницы в номер строк с и по */
PKG_P8PANELS_VISUAL.UTL_ROWS_LIMITS_CALC(NPAGE_NUMBER => NPAGE_NUMBER,
NPAGE_SIZE => NPAGE_SIZE,
NROW_FROM => NROW_FROM,
NROW_TO => NROW_TO);
/* Подготовим поисковую строку для использования в запросе*/
if (SSEARCH is not null) then
PKG_P8PANELS_BASE.UTL_SEARCH_PREPARE(SSEARCH => SSEARCH, SSEARCH_PREPARED => SSEARCH_PREPARED);
end if;
/* Инициализируем таблицу данных */
RDG := PKG_P8PANELS_VISUAL.TDG_MAKE();
/* Добавляем в таблицу описание колонок */
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NRN',
SCAPTION => 'Рег. номер',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NCOST_STATUS',
SCAPTION => 'Статус',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
SHINT => INFO_COST_STATUS_HINT(NTYPE => 1),
BORDER => true);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SCODE',
SCAPTION => 'Код',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BORDER => true);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SNAME_USL',
SCAPTION => 'Условное наименование',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BORDER => true);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SNAME',
SCAPTION => 'Наименование',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BORDER => true);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SEXT_CUST',
SCAPTION => 'Заказчик',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BORDER => true);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SDOC_OSN',
SCAPTION => 'Договор',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BORDER => true);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NSTATE',
SCAPTION => 'Состояние',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
SHINT => INFO_STATE_HINT(),
BORDER => true);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'DBEGPLAN',
SCAPTION => 'Дата начала',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_DATE,
BORDER => true);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'DENDPLAN',
SCAPTION => 'Дата окончания',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_DATE,
BORDER => true);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NCOST_READY',
SCAPTION => 'Готов (%, затраты)',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
SHINT => INFO_COST_READY_HINT(),
BORDER => true);
/* Обходим данные */
begin
/* Добавляем подсказку совместимости */
CSQL := PKG_SQL_BUILD.COMPATIBLE(SSQL => CSQL);
/* Формируем запрос */
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => 'select *');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from (select D.*,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.SQLROWNUM() || ' NROW');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from (select P.RN NRN,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' P.CODE SCODE,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' P.NAME_USL SNAME_USL,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' P.NAME SNAME,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' EC.AGNABBR SEXT_CUST,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' P.DOC_OSN SDOC_OSN,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' P."STATE" NSTATE,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' P.BEGPLAN DBEGPLAN,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' P.ENDPLAN DENDPLAN,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.PKG_NAME(SNAME => 'PKG_P8PANELS_PROJECTS.INFO_COST_STATUS_GET') || '(P.RN) NCOST_STATUS,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.PKG_NAME(SNAME => 'PKG_P8PANELS_PROJECTS.INFO_COST_READY_GET') || '(P.RN) NCOST_READY');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from PROJECT P');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' left outer join AGNLIST EC on P.EXT_CUST = EC.RN');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' left outer join INS_DEPARTMENT SR on P.SUBDIV_RESP = SR.RN,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' PRJTYPE PT');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' where P.COMPANY = :NCOMPANY');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and P.PRJTYPE = PT.RN');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and ((:SPRJ_TYPE is null) or ((:SPRJ_TYPE is not null) and (PT.CODE = :SPRJ_TYPE)))');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and ((:SINS_DEPARTMENT is null) or ((:SINS_DEPARTMENT is not null) and (SR.CODE = :SINS_DEPARTMENT)))');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and ((:NCOST_STATUS = 0) or ((:NCOST_STATUS <> 0) and (' || PKG_SQL_BUILD.PKG_NAME(SNAME => 'PKG_P8PANELS_PROJECTS.INFO_COST_STATUS_GET') || '(P.RN) = :NCOST_STATUS)))');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and ((:NSTATE = 0) or ((:NSTATE <> 0) and (((:NSTATE = 1) and (P.STATE = 1)) or ((:NSTATE = 2) and (P.STATE <> 1)))))');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and ((:SSEARCH_PREPARED is null) or ((:SSEARCH_PREPARED is not null) and (LOWER(P.CODE || P.NAME || P.NAME_USL || EC.AGNABBR) like LOWER(:SSEARCH_PREPARED))))');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and exists (select null from V_USERPRIV UP where UP."CATALOG" = P.CRN)');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and exists (select null from V_USERPRIV UP where UP.JUR_PERS = P.JUR_PERS and UP.UNITCODE = ' || PKG_SQL_BUILD.WRAP_STR(SVALUE => 'Projects') || ')');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' %ORDER_BY%) D) F');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' where F.NROW between :NROW_FROM and :NROW_TO');
/* Учтём сортировки */
PKG_P8PANELS_VISUAL.TDG_ORDERS_SET_QUERY(RDATA_GRID => RDG, RORDERS => RO, SPATTERN => '%ORDER_BY%', CSQL => CSQL);
/* Разбираем его */
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 => 'NCOMPANY', NVALUE => NCOMPANY);
PKG_SQL_DML.BIND_VARIABLE_STR(ICURSOR => ICURSOR, SNAME => 'SPRJ_TYPE', SVALUE => SPRJ_TYPE);
PKG_SQL_DML.BIND_VARIABLE_STR(ICURSOR => ICURSOR, SNAME => 'SINS_DEPARTMENT', SVALUE => SINS_DEPARTMENT);
PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NCOST_STATUS', NVALUE => NCOST_STATUS);
PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NSTATE', NVALUE => NSTATE);
PKG_SQL_DML.BIND_VARIABLE_STR(ICURSOR => ICURSOR, SNAME => 'SSEARCH_PREPARED', SVALUE => SSEARCH_PREPARED);
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_NUM(ICURSOR => ICURSOR, IPOSITION => 7);
PKG_SQL_DML.DEFINE_COLUMN_DATE(ICURSOR => ICURSOR, IPOSITION => 8);
PKG_SQL_DML.DEFINE_COLUMN_DATE(ICURSOR => ICURSOR, IPOSITION => 9);
PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 10);
PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 11);
PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 12);
/* Делаем выборку */
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.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NRN', ICURSOR => ICURSOR, NPOSITION => 1, BCLEAR => true);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SCODE', ICURSOR => ICURSOR, NPOSITION => 2);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SNAME_USL', ICURSOR => ICURSOR, NPOSITION => 3);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SNAME', ICURSOR => ICURSOR, NPOSITION => 4);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SEXT_CUST', ICURSOR => ICURSOR, NPOSITION => 5);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SDOC_OSN', ICURSOR => ICURSOR, NPOSITION => 6);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NSTATE', ICURSOR => ICURSOR, NPOSITION => 7);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLD(RROW => RDG_ROW, SNAME => 'DBEGPLAN', ICURSOR => ICURSOR, NPOSITION => 8);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLD(RROW => RDG_ROW, SNAME => 'DENDPLAN', ICURSOR => ICURSOR, NPOSITION => 9);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NCOST_STATUS', ICURSOR => ICURSOR, NPOSITION => 10);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NCOST_READY', ICURSOR => ICURSOR, NPOSITION => 11);
/* Добавляем строку в таблицу */
PKG_P8PANELS_VISUAL.TDG_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
end loop;
/* Освобождаем курсор */
PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR);
exception
when others then
PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR);
raise;
end;
/* Сериализуем описание */
COUT := PKG_P8PANELS_VISUAL.TDG_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => NINCLUDE_DEF);
end INFO_PROJECTS_DG;
/* Список этапов проекта (таблица данных) */
procedure INFO_STAGES_DG
(
NPROJECT in number, -- Рег. номер проекта
NPAGE_NUMBER in number, -- Номер страницы (игнорируется при NPAGE_SIZE=0)
NPAGE_SIZE in number, -- Количество записей на странице (0 - все)
CORDERS in clob, -- Сортировки
NINCLUDE_DEF in number, -- Признак включения описания колонок таблицы в ответ
COUT out clob -- Сериализованная таблица данных
)
is
NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса
RO PKG_P8PANELS_VISUAL.TDG_ORDERS; -- Сортировки
RDG PKG_P8PANELS_VISUAL.TDG; -- Описание таблицы
RDG_ROW PKG_P8PANELS_VISUAL.TDG_ROW; -- Строка таблицы
NROW_FROM PKG_STD.TREF; -- Номер строки с
NROW_TO PKG_STD.TREF; -- Номер строки по
CSQL clob; -- Буфер для запроса
ICURSOR integer; -- Курсор для исполнения запроса
begin
/* Читаем сортировки */
RO := PKG_P8PANELS_VISUAL.TDG_ORDERS_FROM_XML(CORDERS => CORDERS);
/* Преобразуем номер и размер страницы в номер строк с и по */
PKG_P8PANELS_VISUAL.UTL_ROWS_LIMITS_CALC(NPAGE_NUMBER => NPAGE_NUMBER,
NPAGE_SIZE => NPAGE_SIZE,
NROW_FROM => NROW_FROM,
NROW_TO => NROW_TO);
/* Инициализируем таблицу данных */
RDG := PKG_P8PANELS_VISUAL.TDG_MAKE();
/* Добавляем в таблицу описание колонок */
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NRN',
SCAPTION => 'Рег. номер',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NPRN',
SCAPTION => 'Рег. номер проекта',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NCOST_STATUS',
SCAPTION => 'Статус',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
SHINT => INFO_COST_STATUS_HINT(NTYPE => 1),
BORDER => true);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SFACEACC',
SCAPTION => 'Заказ/этап',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BORDER => true);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'DBEGPLAN',
SCAPTION => 'Начало (план)',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_DATE,
BORDER => true);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'DENDPLAN',
SCAPTION => 'Окончание (план)',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_DATE,
BORDER => true);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NCOST_SUM',
SCAPTION => 'Стоимость',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BORDER => true);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SSUBDIV_RESP',
SCAPTION => 'Исполнитель',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BORDER => true);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SNAME',
SCAPTION => 'Содержание',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BORDER => true);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NCOST_READY',
SCAPTION => 'Готов (%, затраты)',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
SHINT => INFO_COST_READY_HINT(),
BORDER => true);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NSTATE',
SCAPTION => 'Состояние',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
SHINT => INFO_STATE_HINT(),
BORDER => true);
/* Обходим данные */
begin
/* Добавляем подсказку совместимости */
CSQL := PKG_SQL_BUILD.COMPATIBLE(SSQL => CSQL);
/* Формируем запрос */
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => 'select *');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from (select D.*,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.SQLROWNUM() || ' NROW');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from (select T.RN NRN,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' T.PRN NPRN,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' FAC.NUMB SFACEACC,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' T.BEGPLAN DBEGPLAN,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' T.ENDPLAN DENDPLAN,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' T.COST_SUM NCOST_SUM,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' (select I.CODE from INS_DEPARTMENT I where I.RN = T.SUBDIV_RESP) SSUBDIV_RESP,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' T.NAME SNAME,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.PKG_NAME(SNAME => 'PKG_P8PANELS_PROJECTS.INFO_COST_STATUS_GET') || '(T.PRN, T.RN) NCOST_STATUS,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.PKG_NAME(SNAME => 'PKG_P8PANELS_PROJECTS.INFO_COST_READY_GET') || '(T.PRN, T.RN) NCOST_READY,');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' T.STATE NSTATE');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from PROJECTSTAGE T');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' left outer join FACEACC FAC on T.FACEACC = FAC.RN');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' where T.COMPANY = :NCOMPANY');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and T.PRN = :NPROJECT');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and exists (select null from V_USERPRIV UP where UP."CATALOG" = T.CRN)');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and exists (select null from V_USERPRIV UP where UP.JUR_PERS = T.JUR_PERS and UP.UNITCODE = ' || PKG_SQL_BUILD.WRAP_STR(SVALUE => 'Projects') || ')');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' %ORDER_BY%) D) F');
PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' where F.NROW between :NROW_FROM and :NROW_TO');
/* Учтём сортировки */
PKG_P8PANELS_VISUAL.TDG_ORDERS_SET_QUERY(RDATA_GRID => RDG,
RORDERS => RO,
SPATTERN => '%ORDER_BY%',
CSQL => CSQL);
/* Разбираем его */
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 => 'NCOMPANY', NVALUE => NCOMPANY);
PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NPROJECT', NVALUE => NPROJECT);
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_NUM(ICURSOR => ICURSOR, IPOSITION => 2);
PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 3);
PKG_SQL_DML.DEFINE_COLUMN_DATE(ICURSOR => ICURSOR, IPOSITION => 4);
PKG_SQL_DML.DEFINE_COLUMN_DATE(ICURSOR => ICURSOR, IPOSITION => 5);
PKG_SQL_DML.DEFINE_COLUMN_NUM(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_NUM(ICURSOR => ICURSOR, IPOSITION => 9);
PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 10);
PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 11);
/* Делаем выборку */
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.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NRN', ICURSOR => ICURSOR, NPOSITION => 1, BCLEAR => true);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NPRN', ICURSOR => ICURSOR, NPOSITION => 2);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SFACEACC', ICURSOR => ICURSOR, NPOSITION => 3);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLD(RROW => RDG_ROW, SNAME => 'DBEGPLAN', ICURSOR => ICURSOR, NPOSITION => 4);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLD(RROW => RDG_ROW, SNAME => 'DENDPLAN', ICURSOR => ICURSOR, NPOSITION => 5);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NCOST_SUM', ICURSOR => ICURSOR, NPOSITION => 6);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SSUBDIV_RESP', ICURSOR => ICURSOR, NPOSITION => 7);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SNAME', ICURSOR => ICURSOR, NPOSITION => 8);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NCOST_STATUS', ICURSOR => ICURSOR, NPOSITION => 9);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NCOST_READY', ICURSOR => ICURSOR, NPOSITION => 10);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NSTATE', ICURSOR => ICURSOR, NPOSITION => 11);
/* Добавляем строку в таблицу */
PKG_P8PANELS_VISUAL.TDG_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
end loop;
/* Освобождаем курсор */
PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR);
exception
when others then
PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR);
raise;
end;
/* Сериализуем описание */
COUT := PKG_P8PANELS_VISUAL.TDG_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => NINCLUDE_DEF);
end INFO_STAGES_DG;
/* Информация об этапе проекта (таблица данных) */
procedure INFO_STAGE_DTL_DG
(
NPROJECTSTAGE in number, -- Рег. номер этапа проекта
COUT out clob -- Сериализованная таблица данных
)
is
RDG PKG_P8PANELS_VISUAL.TDG; -- Описание таблицы
RDG_ROW PKG_P8PANELS_VISUAL.TDG_ROW; -- Строка таблицы
begin
/* Инициализируем таблицу данных */
RDG := PKG_P8PANELS_VISUAL.TDG_MAKE();
/* Добавляем в таблицу описание колонок */
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SCODE',
SCAPTION => 'Код',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SATTR',
SCAPTION => 'Атрибут',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SVALUE',
SCAPTION => 'Значение',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR);
/* Обратимся к данным этапа проекта */
for REC in (select (select F.NUMB from FACEACC F where F.RN = T.FACEACC) SFACEACC,
trim(T.NUMB) SNUMB,
M.NAME_USL SNAME_USL,
T.NAME SNAME,
(select A.AGNABBR from AGNLIST A where A.RN = M.EXT_CUST) SEXT_CUST,
M.DOC_OSN SDOC_OSN,
(select TO_CHAR(C.DOC_DATE, 'dd.mm.yyyy')
from DOCLINKS DL, CONTRACTS C
where DL.IN_DOCUMENT = M.RN and DL.IN_UNITCODE = 'Projects' and DL.OUT_UNITCODE = 'Contracts' and C.RN = DL.OUT_DOCUMENT and ROWNUM = 1) SDOC_OSN_DATE,
M.COST_SUM NCOST_SUM,
T.COST_SUM NSTAGE_COST_SUM,
(select CUR.INTCODE from CURNAMES CUR where CUR.RN = M.CURNAMES) SCURNAMES,
(select I.CODE from INS_DEPARTMENT I where I.RN = T.SUBDIV_RESP) SSUBDIV_RESP,
(select A.AGNABBR from AGNLIST A where A.RN = T.RESPONSIBLE) SRESPONSIBLE,
TO_CHAR(T.BEGPLAN, 'dd.mm.yyyy') SBEGPLAN,
TO_CHAR(T.ENDPLAN, 'dd.mm.yyyy') SENDPLAN,
T.STATE NSTATE,
T.NAME SCONTENT,
T.NOTE SNOTE
from PROJECTSTAGE T,
PROJECT M
where T.RN = NPROJECTSTAGE
and M.RN = T.PRN)
loop
/* Формируем группу - Общие характеристики */
PKG_P8PANELS_VISUAL.TDG_ADD_GROUP(RDATA_GRID => RDG, SNAME => 'COMMON', SCAPTION => 'Общие', BEXPANDABLE => true, BEXPANDED => true);
RDG_ROW := PKG_P8PANELS_VISUAL.TDG_ROW_MAKE(SGROUP => 'COMMON');
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SCODE', SVALUE => 'SFACEACC', BCLEAR => true);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SATTR', SVALUE => 'Заказ');
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SVALUE', SVALUE => REC.SFACEACC);
PKG_P8PANELS_VISUAL.TDG_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SCODE', SVALUE => 'SNUMB', BCLEAR => true);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SATTR', SVALUE => 'Номер этапа');
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SVALUE', SVALUE => REC.SNUMB);
PKG_P8PANELS_VISUAL.TDG_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SCODE', SVALUE => 'SNAME_USL', BCLEAR => true);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SATTR', SVALUE => 'Тема');
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SVALUE', SVALUE => REC.SNAME_USL);
PKG_P8PANELS_VISUAL.TDG_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SCODE', SVALUE => 'SNAME', BCLEAR => true);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SATTR', SVALUE => 'Наименование');
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SVALUE', SVALUE => REC.SNAME);
PKG_P8PANELS_VISUAL.TDG_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SCODE', SVALUE => 'SEXT_CUST', BCLEAR => true);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SATTR', SVALUE => 'Заказчик');
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SVALUE', SVALUE => REC.SEXT_CUST);
PKG_P8PANELS_VISUAL.TDG_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SCODE', SVALUE => 'SDOC_OSN', BCLEAR => true);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SATTR', SVALUE => 'Договор');
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SVALUE', SVALUE => REC.SDOC_OSN);
PKG_P8PANELS_VISUAL.TDG_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SCODE', SVALUE => 'SDOC_OSN_DATE', BCLEAR => true);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SATTR', SVALUE => 'Дата договора');
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SVALUE', SVALUE => REC.SDOC_OSN_DATE);
PKG_P8PANELS_VISUAL.TDG_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SCODE', SVALUE => 'NCOST_SUM', BCLEAR => true);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SATTR', SVALUE => 'Стоимость заказа');
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SVALUE', SVALUE => REC.NCOST_SUM);
PKG_P8PANELS_VISUAL.TDG_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SCODE', SVALUE => 'NSTAGE_COST_SUM', BCLEAR => true);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SATTR', SVALUE => 'Стоимость этапа');
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SVALUE', SVALUE => REC.NSTAGE_COST_SUM);
PKG_P8PANELS_VISUAL.TDG_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SCODE', SVALUE => 'SCURNAMES', BCLEAR => true);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SATTR', SVALUE => 'Валюта');
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SVALUE', SVALUE => REC.SCURNAMES);
PKG_P8PANELS_VISUAL.TDG_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
/* Формируем группу - Контроль */
PKG_P8PANELS_VISUAL.TDG_ADD_GROUP(RDATA_GRID => RDG, SNAME => 'CONTROL', SCAPTION => 'Контроль', BEXPANDABLE => true, BEXPANDED => true);
RDG_ROW := PKG_P8PANELS_VISUAL.TDG_ROW_MAKE(SGROUP => 'CONTROL');
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SCODE', SVALUE => 'SSUBDIV_RESP', BCLEAR => true);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SATTR', SVALUE => 'Головной исполнитель');
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SVALUE', SVALUE => REC.SSUBDIV_RESP);
PKG_P8PANELS_VISUAL.TDG_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SCODE', SVALUE => 'SRESPONSIBLE', BCLEAR => true);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SATTR', SVALUE => 'Ответственный');
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SVALUE', SVALUE => REC.SRESPONSIBLE);
PKG_P8PANELS_VISUAL.TDG_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
/* Формируем группу - Работы */
PKG_P8PANELS_VISUAL.TDG_ADD_GROUP(RDATA_GRID => RDG, SNAME => 'WORKS', SCAPTION => 'Работы', BEXPANDABLE => true, BEXPANDED => true);
RDG_ROW := PKG_P8PANELS_VISUAL.TDG_ROW_MAKE(SGROUP => 'WORKS');
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SCODE', SVALUE => 'SBEGPLAN', BCLEAR => true);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SATTR', SVALUE => 'Начало работ');
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SVALUE', SVALUE => REC.SBEGPLAN);
PKG_P8PANELS_VISUAL.TDG_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SCODE', SVALUE => 'SENDPLAN', BCLEAR => true);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SATTR', SVALUE => 'Окончание работ');
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SVALUE', SVALUE => REC.SENDPLAN);
PKG_P8PANELS_VISUAL.TDG_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SCODE', SVALUE => 'NSTATE', BCLEAR => true);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SATTR', SVALUE => 'Состояние');
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SVALUE', SVALUE => REC.NSTATE);
PKG_P8PANELS_VISUAL.TDG_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SCODE', SVALUE => 'SCONTENT', BCLEAR => true);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SATTR', SVALUE => 'Содержание');
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SVALUE', SVALUE => REC.SCONTENT);
PKG_P8PANELS_VISUAL.TDG_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
/* Формируем группу - Дополнительно */
PKG_P8PANELS_VISUAL.TDG_ADD_GROUP(RDATA_GRID => RDG, SNAME => 'EXTRA', SCAPTION => 'Дополнительно', BEXPANDABLE => true, BEXPANDED => false);
RDG_ROW := PKG_P8PANELS_VISUAL.TDG_ROW_MAKE(SGROUP => 'EXTRA');
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SCODE', SVALUE => 'SNOTE', BCLEAR => true);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SATTR', SVALUE => 'Примечание');
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SVALUE', SVALUE => REC.SNOTE);
PKG_P8PANELS_VISUAL.TDG_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
end loop;
/* Сериализуем описание */
COUT := PKG_P8PANELS_VISUAL.TDG_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => 1);
end INFO_STAGE_DTL_DG;
/* Структура цены этапа проекта (состав статей) */
procedure INFO_STAGE_ARTS_GET
(
NPROJECTSTAGE in number, -- Рег. номер этапа проекта
RINFO_STAGE_ARTS out TINFO_STAGE_ARTS -- Список статей структуры цены этапа проекта
)
is
I PKG_STD.TNUMBER; -- Счётчик статей в результирующей коллекции
begin
/* Инициализируем коллекцию */
RINFO_STAGE_ARTS := TINFO_STAGE_ARTS();
/* Подбираем активную структуру цены этапа проекта и её обходим статьи */
for C in (select CSPA.RN NRN,
-1 NCOST_STATUS,
PS.FACEACC NFACEACC,
A.RN NFPDARTCL,
A.CODE SFPDARTCL,
CSPA.COST_SUM NPLAN_SUM,
null NFACT_SUM,
null NPLAN_FACT_SUM,
C.INTCODE SCURNAMES
from PROJECTSTAGE PS,
STAGES CS,
FACEACC FC,
CONTRPRSTRUCT CSP,
CONTRPRCLC CSPA,
FPDARTCL A,
CURNAMES C
where PS.RN = NPROJECTSTAGE
and PS.FACEACCCUST = CS.FACEACC
and CS.FACEACC = FC.RN
and FC.CURRENCY = C.RN
and CSP.PRN = CS.RN
and CSP.RN = INFO_CONTRPRSTRUCT_ACTIVE_FIND(PS.RN)
and CSPA.PRN = CSP.RN
and CSPA.COST_ARTICLE = A.RN
and exists (select null from V_USERPRIV UP where UP.CATALOG = PS.CRN)
and exists (select null
from V_USERPRIV UP
where UP.JUR_PERS = PS.JUR_PERS
and UP.UNITCODE = 'Projects')
and exists (select null from V_USERPRIV UP where UP.CATALOG = CS.CRN)
and exists (select null
from V_USERPRIV UP
where UP.JUR_PERS = CS.JUR_PERS
and UP.UNITCODE = 'Contracts')
order by CSPA.NUMB)
loop
/* Добавим строку в коллекцию */
RINFO_STAGE_ARTS.EXTEND();
I := RINFO_STAGE_ARTS.LAST;
/* Наполним её значениями из хранилища */
RINFO_STAGE_ARTS(I).NRN := C.NRN;
RINFO_STAGE_ARTS(I).NCOST_STATUS := C.NCOST_STATUS;
RINFO_STAGE_ARTS(I).NFACEACC := C.NFACEACC;
RINFO_STAGE_ARTS(I).NFPDARTCL := C.NFPDARTCL;
RINFO_STAGE_ARTS(I).SFPDARTCL := C.SFPDARTCL;
RINFO_STAGE_ARTS(I).NPLAN_SUM := C.NPLAN_SUM;
RINFO_STAGE_ARTS(I).NFACT_SUM := C.NFACT_SUM;
RINFO_STAGE_ARTS(I).NPLAN_FACT_SUM := C.NPLAN_FACT_SUM;
RINFO_STAGE_ARTS(I).SCURNAMES := C.SCURNAMES;
RINFO_STAGE_ARTS(I).NCOST_CTL := INFO_FPDARTCL_COST_IS_CTL(NRN => C.NFPDARTCL);
/* Для статей, подлежащих контролю затрат */
if (RINFO_STAGE_ARTS(I).NCOST_CTL) then
/* Определим фактические затраты */
RINFO_STAGE_ARTS(I).NFACT_SUM := INFO_FCCOSTNOTES_FACT_GET(NFACEACC => RINFO_STAGE_ARTS(I).NFACEACC,
NFPDARTCL => RINFO_STAGE_ARTS(I).NFPDARTCL);
/* Определим отклонение */
RINFO_STAGE_ARTS(I).NPLAN_FACT_SUM := RINFO_STAGE_ARTS(I).NPLAN_SUM - RINFO_STAGE_ARTS(I).NFACT_SUM;
/* Определим статус затрат - если сумма фактических затрат больше плановых - это перерасход*/
if (RINFO_STAGE_ARTS(I).NFACT_SUM > RINFO_STAGE_ARTS(I).NPLAN_SUM) then
RINFO_STAGE_ARTS(I).NCOST_STATUS := 2;
else
/* Если отношение факт/план >= 0.9 - опасность */
if ((RINFO_STAGE_ARTS(I).NPLAN_SUM <> 0) and
(RINFO_STAGE_ARTS(I).NFACT_SUM / RINFO_STAGE_ARTS(I).NPLAN_SUM >= 0.9)) then
RINFO_STAGE_ARTS(I).NCOST_STATUS := 1;
else
/* Отклонений нет */
RINFO_STAGE_ARTS(I).NCOST_STATUS := 0;
end if;
end if;
end if;
end loop;
end INFO_STAGE_ARTS_GET;
/* Структура цены этапа проекта (таблица данных) */
procedure INFO_STAGE_ARTS_DG
(
NPROJECTSTAGE in number, -- Рег. номер этапа проекта
COUT out clob -- Сериализованная таблица данных
)
is
RINFO_STAGE_ARTS TINFO_STAGE_ARTS; -- Список статей структуры цены
RDG PKG_P8PANELS_VISUAL.TDG; -- Описание таблицы
RDG_ROW PKG_P8PANELS_VISUAL.TDG_ROW; -- Строка таблицы
begin
/* Инициализируем таблицу данных */
RDG := PKG_P8PANELS_VISUAL.TDG_MAKE();
/* Добавляем в таблицу описание колонок */
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NRN',
SCAPTION => 'Рег. номер',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NCOST_STATUS',
SCAPTION => 'Статус',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
SHINT => INFO_COST_STATUS_HINT(NTYPE => 0));
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NFACEACC',
SCAPTION => 'Рег. номер лицевого счета затрат',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NFPDARTCL',
SCAPTION => 'Рег. номер статьи',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BVISIBLE => false);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SFPDARTCL',
SCAPTION => 'Статья',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NPLAN_SUM',
SCAPTION => 'План',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NFACT_SUM',
SCAPTION => 'Факт',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'NPLAN_FACT_SUM',
SCAPTION => 'Отклонение',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB);
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SCURNAMES',
SCAPTION => 'Валюта',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR);
/* Сформируем список статей структуры цены */
INFO_STAGE_ARTS_GET(NPROJECTSTAGE => NPROJECTSTAGE, RINFO_STAGE_ARTS => RINFO_STAGE_ARTS);
/* Обходим собранные статьи */
if ((RINFO_STAGE_ARTS is not null) and (RINFO_STAGE_ARTS.COUNT > 0)) then
for I in RINFO_STAGE_ARTS.FIRST .. RINFO_STAGE_ARTS.LAST
loop
/* Добавляем колонки с данными */
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW,
SNAME => 'NRN',
NVALUE => RINFO_STAGE_ARTS(I).NRN,
BCLEAR => true);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW,
SNAME => 'NCOST_STATUS',
NVALUE => RINFO_STAGE_ARTS(I).NCOST_STATUS);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NFACEACC', NVALUE => RINFO_STAGE_ARTS(I).NFACEACC);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NFPDARTCL', NVALUE => RINFO_STAGE_ARTS(I).NFPDARTCL);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SFPDARTCL', SVALUE => RINFO_STAGE_ARTS(I).SFPDARTCL);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NPLAN_SUM', NVALUE => RINFO_STAGE_ARTS(I).NPLAN_SUM);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NFACT_SUM', NVALUE => RINFO_STAGE_ARTS(I).NFACT_SUM);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW,
SNAME => 'NPLAN_FACT_SUM',
NVALUE => RINFO_STAGE_ARTS(I).NPLAN_FACT_SUM);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SCURNAMES', SVALUE => RINFO_STAGE_ARTS(I).SCURNAMES);
/* Добавляем строку в таблицу */
PKG_P8PANELS_VISUAL.TDG_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
end loop;
end if;
/* Сериализуем описание */
COUT := PKG_P8PANELS_VISUAL.TDG_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => 1);
end INFO_STAGE_ARTS_DG;
/* Структура цены этапа проекта (график) */
procedure INFO_STAGE_ARTS_CHART
(
NPROJECTSTAGE in number, -- Рег. номер этапа проекта
NTYPE in number, -- Тип диаграммы (0 - по плану, 1 - по факту)
COUT out clob -- Сериализованный график
)
is
RINFO_STAGE_ARTS TINFO_STAGE_ARTS; -- Список статей структуры цены
RCH PKG_P8PANELS_VISUAL.TCHART; -- График
RCH_DS PKG_P8PANELS_VISUAL.TCHART_DATASET; -- Набор данных
RATTR_VALS PKG_P8PANELS_VISUAL.TCHART_DATASET_ITEM_ATTR_VALS; -- Атрибуты элемента набора данных
begin
/* Сформируем заголовок графика */
RCH := PKG_P8PANELS_VISUAL.TCHART_MAKE(STYPE => PKG_P8PANELS_VISUAL.SCHART_TYPE_PIE,
SLGND_POS => PKG_P8PANELS_VISUAL.SCHART_LGND_POS_RIGHT);
/* Сформируем набор данных графика */
RCH_DS := PKG_P8PANELS_VISUAL.TCHART_DATASET_MAKE(SCAPTION => 'Сумма');
/* Сформируем список статей структуры цены */
INFO_STAGE_ARTS_GET(NPROJECTSTAGE => NPROJECTSTAGE, RINFO_STAGE_ARTS => RINFO_STAGE_ARTS);
/* Обходим собранные статьи */
if ((RINFO_STAGE_ARTS is not null) and (RINFO_STAGE_ARTS.COUNT > 0)) then
for I in RINFO_STAGE_ARTS.FIRST .. RINFO_STAGE_ARTS.LAST
loop
/* Только статьи, подлежащие контролю затрат */
if (INFO_FPDARTCL_COST_IS_CTL(NRN => RINFO_STAGE_ARTS(I).NFPDARTCL)) then
/* Добавим метку для статьи */
PKG_P8PANELS_VISUAL.TCHART_ADD_LABEL(RCHART => RCH, SLABEL => RINFO_STAGE_ARTS(I).SFPDARTCL);
/* Сформируем дополнительные атрибуты для клиентского приложения - лицевой счет и рег. номер статьи затрат (будут применяться при открытии ЖЗ)*/
PKG_P8PANELS_VISUAL.TCHART_DATASET_ITM_ATTR_VL_ADD(RATTR_VALS => RATTR_VALS,
SNAME => 'NFACEACC',
SVALUE => TO_CHAR(RINFO_STAGE_ARTS(I).NFACEACC),
BCLEAR => true);
PKG_P8PANELS_VISUAL.TCHART_DATASET_ITM_ATTR_VL_ADD(RATTR_VALS => RATTR_VALS,
SNAME => 'NFPDARTCL',
SVALUE => TO_CHAR(RINFO_STAGE_ARTS(I).NFPDARTCL));
/* Исходим от типа диаграммы */
if (NTYPE = 0) then
/* Добавим данные по плану */
PKG_P8PANELS_VISUAL.TCHART_DATASET_ADD_ITEM(RDATASET => RCH_DS,
NVALUE => RINFO_STAGE_ARTS(I).NPLAN_SUM,
RATTR_VALS => RATTR_VALS);
else
/* Добавим данные по факту */
PKG_P8PANELS_VISUAL.TCHART_DATASET_ADD_ITEM(RDATASET => RCH_DS,
NVALUE => RINFO_STAGE_ARTS(I).NFACT_SUM,
RATTR_VALS => RATTR_VALS);
end if;
end if;
end loop;
end if;
/* Добавим набор данных в график */
PKG_P8PANELS_VISUAL.TCHART_ADD_DATASET(RCHART => RCH, RDATASET => RCH_DS);
/* Сериализуем описание */
COUT := PKG_P8PANELS_VISUAL.TCHART_TO_XML(RCHART => RCH, NINCLUDE_DEF => 1);
end INFO_STAGE_ARTS_CHART;
end PKG_P8PANELS_PROJECTS;
/