create or replace package PKG_P8PANELS_PROJECTS as /* Типы данных - статьи этапа проекта */ type TSTAGE_ART is record ( NRN FPDARTCL.RN%type, -- Рег. номер статьи SCODE FPDARTCL.CODE%type, -- Код статьи SNAME FPDARTCL.NAME%type, -- Наименование статьи NPLAN PKG_STD.TNUMBER, -- Плановое значение по статье NCOST_FACT PKG_STD.TNUMBER, -- Фактические затраты (null - не подлежит контролю затрат) NCOST_DIFF PKG_STD.TNUMBER, -- Отклонение по затратам (null - не подлежит контролю затрат) NCTRL_COST PKG_STD.TNUMBER, -- Контроль затрат (null - не подлежит контролю затрат, 0 - без отклонений, 1 - есть отклонения) NCONTR PKG_STD.TNUMBER, -- Законтрактовано (null - не подлежит контролю контрактации) NCONTR_LEFT PKG_STD.TNUMBER, -- Остаток к контрактации (null - не подлежит контролю контрактации) NCTRL_CONTR PKG_STD.TNUMBER -- Контроль контрактации (null - не подлежит контролю контрактации, 0 - без отклонений, 1 - есть отклонения) ); /* Типы данных - коллекция статей этапа проекта */ type TSTAGE_ARTS is table of TSTAGE_ART; /* Отбор проектов */ procedure COND; /* Получение рег. номера документа основания (договора) проекта */ function GET_DOC_OSN_LNK_DOCUMENT ( NRN in number -- Рег. номер проекта ) return number; -- Рег. номер документа основания (договора) /* Подбор платежей финансирования проекта */ procedure SELECT_FIN ( NRN in number, -- Рег. номер проекта NDIRECTION in number, -- Направление (0 - приход, 1 - расход) NIDENT out number -- Идентификатор буфера подобранных (списка отмеченных записей, null - не найдено) ); /* Получение суммы входящего финансирования проекта */ function GET_FIN_IN ( NRN in number -- Рег. номер проекта ) return number; -- Сумма входящего финансирования проекта /* Получение суммы исходящего финансирования проекта */ function GET_FIN_OUT ( NRN in number -- Рег. номер проекта ) return number; -- Сумма исходяшего финансирования проекта /* Получение состояния финансирования проекта */ function GET_CTRL_FIN ( NRN in number -- Рег. номер проекта ) return number; -- Состояние (null - не определено, 0 - без отклонений, 1 - есть отклонения) /* Получение состояния контрактации проекта */ function GET_CTRL_CONTR ( NRN in number -- Рег. номер проекта ) return number; -- Состояние (null - не определено, 0 - без отклонений, 1 - есть отклонения) /* Получение состояния соисполнения проекта */ function GET_CTRL_COEXEC ( NRN in number -- Рег. номер проекта ) return number; -- Состояние (null - не определено, 0 - без отклонений, 1 - есть отклонения) /* Получение состояния сроков проекта */ function GET_CTRL_PERIOD ( NRN in number -- Рег. номер проекта ) return number; -- Состояние (null - не определено, 0 - без отклонений, 1 - есть отклонения) /* Получение состояния затрат проекта */ function GET_CTRL_COST ( NRN in number -- Рег. номер проекта ) return number; -- Состояние (null - не определено, 0 - без отклонений, 1 - есть отклонения) /* Получение состояния актирования проекта */ function GET_CTRL_ACT ( NRN in number -- Рег. номер проекта ) return number; -- Состояние (null - не определено, 0 - без отклонений, 1 - есть отклонения) /* Получение % готовности проекта (по затратам) */ 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 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, -- Новая дата окончания DBEGIN in date, -- Дата начала периода мониторинга загрузки ресурсов NRESOURCE_STATUS out number -- Состояние ресурсов (0 - без отклонений, 1 - есть отклонения) ); /* Получение списка работ проектов для диаграммы Ганта */ procedure JB_JOBS_LIST ( NIDENT in number, -- Идентификатор процесса NPRN in number, -- Рег. номер родителя NINCLUDE_DEF in number, -- Признак включения описания диаграммы в ответ COUT out clob -- Список проектов ); /* Получение списка для детализации трудоёмкости по ФОТ периода балансировки */ procedure JB_PERIODS_LIST_PLAN_FOT ( 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_LIST_PLAN_JOBS ( 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, -- Идентификатор процесса DBEGIN in date, -- Дата начала периода мониторинга загрузки ресурсов 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_INIT ( DBEGIN in out date, -- Дата начала периода мониторинга загрузки ресурсов DFACT in out date, -- Факт по состоянию на NDURATION_MEAS in out number, -- Единица измерения длительности (0 - день, 1 - неделя, 2 - декада, 3 - месяц, 4 - квартал, 5 - год) SLAB_MEAS in out varchar2, -- Единица измерения трудоёмкости NIDENT in out number, -- Идентификатор буфера сформированных данных (null - сгенерировать новый, !null - удалить старые данные и пересоздать с указанным идентификатором) NRESOURCE_STATUS out number -- Состояние ресурсов (0 - без отклонений, 1 - есть отклонения) ); end PKG_P8PANELS_PROJECTS; / create or replace package body PKG_P8PANELS_PROJECTS as /* TODO: owner="root" created="25.10.2023" text="Пересчёт единиц измерения в мониторе плана-графика" */ /* TODO: owner="root" created="25.10.2023" text="Буфер для хранения параметров балансировки и читать их оттуда для вызовов JB_JOBS_MODIFY_PERIOD, JB_JOBS_PERIODS_RECALC" */ /* TODO: owner="root" created="25.10.2023" text="Права доступа в мониторе ресурвов при балансировке планов-графиков" */ /* TODO: owner="root" created="25.10.2023" text="Признак измененности на работах, чтобы удобнее было переносить в проект" */ /* TODO: owner="root" created="25.10.2023" text="Вынести расчте плановой трудоёмкости по графику (и всех её причендалов) в отдельную функцию (и), чтобы можно было включить её в динамический запрос и вернуть сортировку по полям трудоёмкости в JB_PERIODS_LIST_PLAN_JOBS" */ /* TODO: owner="root" created="25.10.2023" text="Проверить, что для расчётных полей дата-гридов отключена сортировка - иначе получается ошибка, т.к. поля нет в SQL-запросе" */ /* Константы - предопределённые значения */ 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 := 'Ч/Ч'; -- Единица измерения трудоёмкости по умолчанию для интерфейса балансировки работ /* Константы - дополнительные свойства */ 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; /* Отбор проектов */ procedure COND as begin /* Установка главной таблицы */ PKG_COND_BROKER.SET_TABLE(STABLE_NAME => 'PROJECT'); /* Тип проекта */ PKG_COND_BROKER.ADD_CONDITION_CODE(SCOLUMN_NAME => 'CODE', SCONDITION_NAME => 'EDPROJECTTYPE', SJOINS => 'PRJTYPE <- RN;PRJTYPE'); /* Мнемокод */ PKG_COND_BROKER.ADD_CONDITION_CODE(SCOLUMN_NAME => 'CODE', SCONDITION_NAME => 'EDMNEMO'); /* Наименование */ PKG_COND_BROKER.ADD_CONDITION_CODE(SCOLUMN_NAME => 'NAME', SCONDITION_NAME => 'EDNAME'); /* Услованое наименование */ PKG_COND_BROKER.ADD_CONDITION_CODE(SCOLUMN_NAME => 'NAME_USL', SCONDITION_NAME => 'EDNAME_USL'); /* Дата начала план */ PKG_COND_BROKER.ADD_CONDITION_BETWEEN(SCOLUMN_NAME => 'BEGPLAN', SCONDITION_NAME_FROM => 'EDPLANBEGFrom', SCONDITION_NAME_TO => 'EDPLANBEGTo'); /* Дата окончания план */ PKG_COND_BROKER.ADD_CONDITION_BETWEEN(SCOLUMN_NAME => 'ENDPLAN', SCONDITION_NAME_FROM => 'EDPLANENDFrom', SCONDITION_NAME_TO => 'EDPLANENDTo'); /* Состояние */ PKG_COND_BROKER.ADD_CONDITION_ENUM(SCOLUMN_NAME => 'STATE', SCONDITION_NAME => 'CGSTATE'); /* Заказчик */ PKG_COND_BROKER.ADD_CONDITION_CODE(SCOLUMN_NAME => 'AGNABBR', SCONDITION_NAME => 'EDEXT_CUST', SJOINS => 'EXT_CUST <- RN;AGNLIST'); /* Контроль финансирования */ if (PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'EDCTRL_FIN') = 1) then PKG_COND_BROKER.ADD_CLAUSE(SCLAUSE => 'PKG_P8PANELS_PROJECTS.GET_CTRL_FIN(RN) = :EDCTRL_FIN'); PKG_COND_BROKER.BIND_VARIABLE(SVARIABLE_NAME => 'EDCTRL_FIN', NVALUE => PKG_COND_BROKER.GET_CONDITION_NUM(SCONDITION_NAME => 'EDCTRL_FIN')); end if; /* Контроль контрактации */ if (PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'EDCTRL_CONTR') = 1) then PKG_COND_BROKER.ADD_CLAUSE(SCLAUSE => 'PKG_P8PANELS_PROJECTS.GET_CTRL_CONTR(RN) = :EDCTRL_CONTR'); PKG_COND_BROKER.BIND_VARIABLE(SVARIABLE_NAME => 'EDCTRL_CONTR', NVALUE => PKG_COND_BROKER.GET_CONDITION_NUM(SCONDITION_NAME => 'EDCTRL_CONTR')); end if; /* Контроль соисполнения */ if (PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'EDCTRL_COEXEC') = 1) then PKG_COND_BROKER.ADD_CLAUSE(SCLAUSE => 'PKG_P8PANELS_PROJECTS.GET_CTRL_COEXEC(RN) = :EDCTRL_COEXEC'); PKG_COND_BROKER.BIND_VARIABLE(SVARIABLE_NAME => 'EDCTRL_COEXEC', NVALUE => PKG_COND_BROKER.GET_CONDITION_NUM(SCONDITION_NAME => 'EDCTRL_COEXEC')); end if; /* Контроль сроков */ if (PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'EDCTRL_PERIOD') = 1) then PKG_COND_BROKER.ADD_CLAUSE(SCLAUSE => 'PKG_P8PANELS_PROJECTS.GET_CTRL_PERIOD(RN) = :EDCTRL_PERIOD'); PKG_COND_BROKER.BIND_VARIABLE(SVARIABLE_NAME => 'EDCTRL_PERIOD', NVALUE => PKG_COND_BROKER.GET_CONDITION_NUM(SCONDITION_NAME => 'EDCTRL_PERIOD')); end if; /* Контроль затрат */ if (PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'EDCTRL_COST') = 1) then PKG_COND_BROKER.ADD_CLAUSE(SCLAUSE => 'PKG_P8PANELS_PROJECTS.GET_CTRL_COST(RN) = :EDCTRL_COST'); PKG_COND_BROKER.BIND_VARIABLE(SVARIABLE_NAME => 'EDCTRL_COST', NVALUE => PKG_COND_BROKER.GET_CONDITION_NUM(SCONDITION_NAME => 'EDCTRL_COST')); end if; /* Контроль актирования */ if (PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'EDCTRL_ACT') = 1) then PKG_COND_BROKER.ADD_CLAUSE(SCLAUSE => 'PKG_P8PANELS_PROJECTS.GET_CTRL_ACT(RN) = :EDCTRL_ACT'); PKG_COND_BROKER.BIND_VARIABLE(SVARIABLE_NAME => 'EDCTRL_ACT', NVALUE => PKG_COND_BROKER.GET_CONDITION_NUM(SCONDITION_NAME => 'EDCTRL_ACT')); end if; /* Готовность (%, по затратам) */ 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_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_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_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.TFILTERS; -- Фильтры RO PKG_P8PANELS_VISUAL.TORDERS; -- Сортировки RDG PKG_P8PANELS_VISUAL.TDATA_GRID; -- Описание таблицы RDG_ROW PKG_P8PANELS_VISUAL.TROW; -- Строка таблицы RCOL_VALS PKG_P8PANELS_VISUAL.TCOL_VALS; -- Предопределённые значения столбцов NROW_FROM PKG_STD.TREF; -- Номер строки с NROW_TO PKG_STD.TREF; -- Номер строки по CSQL clob; -- Буфер для запроса ICURSOR integer; -- Курсор для исполнения запроса NECON_RESP_DP PKG_STD.TREF; -- Рег. номер ДС "Ответственный экономист" begin /* Читаем фильтры */ RF := PKG_P8PANELS_VISUAL.TFILTERS_FROM_XML(CFILTERS => CFILTERS); /* Читем сортировки */ RO := PKG_P8PANELS_VISUAL.TORDERS_FROM_XML(CORDERS => CORDERS); /* Преобразуем номер и размер страницы в номер строк с и по */ PKG_P8PANELS_VISUAL.UTL_ROWS_LIMITS_CALC(NPAGE_NUMBER => NPAGE_NUMBER, NPAGE_SIZE => NPAGE_SIZE, NROW_FROM => NROW_FROM, NROW_TO => NROW_TO); /* Инициализируем таблицу данных */ RDG := PKG_P8PANELS_VISUAL.TDATA_GRID_MAKE(); /* Добавляем в таблицу описание колонок */ PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NRN', SCAPTION => 'Рег. номер', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SCODE', SCAPTION => 'Код', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, SCOND_FROM => 'EDMNEMO', BORDER => true, BFILTER => true); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SNAME', SCAPTION => 'Наименование', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, SCOND_FROM => 'EDNAME', BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SNAME_USL', SCAPTION => 'Условное наименование', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, SCOND_FROM => 'EDNAME_USL', BORDER => true, BFILTER => true); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SEXPECTED_RES', SCAPTION => 'Ожидаемые результаты', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SPRJTYPE', SCAPTION => 'Тип', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, SCOND_FROM => 'EDPROJECTTYPE', BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SEXT_CUST', SCAPTION => 'Заказчик', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, SCOND_FROM => 'EDEXT_CUST', BORDER => true, BFILTER => true); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SGOVCNTRID', SCAPTION => 'ИГК', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SDOC_OSN', SCAPTION => 'Документ-основание', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SLNK_UNIT_SDOC_OSN', SCAPTION => 'Документ-основание (код раздела ссылки)', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NLNK_DOCUMENT_SDOC_OSN', SCAPTION => 'Документ-основание (документ ссылки)', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SSUBDIV_RESP', SCAPTION => 'Подразделение-исполнитель', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SRESPONSIBLE', SCAPTION => 'Ответственный исполнитель', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SECON_RESP', SCAPTION => 'Ответственный экономист', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, BVISIBLE => false); PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 0, BCLEAR => true); PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 1); PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 2); PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 3); PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 4); PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 5); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NSTATE', SCAPTION => 'Состояние', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, SCOND_FROM => 'CGSTATE', BORDER => true, BFILTER => true, RCOL_VALS => RCOL_VALS); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'DBEGPLAN', SCAPTION => 'Дата начала', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_DATE, SCOND_FROM => 'EDPLANBEGFrom', SCOND_TO => 'EDPLANBEGTo', BORDER => true, BFILTER => true); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'DENDPLAN', SCAPTION => 'Дата окончания', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_DATE, SCOND_FROM => 'EDPLANENDFrom', SCOND_TO => 'EDPLANENDTo', BORDER => true, BFILTER => true); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NCOST_SUM', SCAPTION => 'Стоимость', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SCURNAMES', SCAPTION => 'Валюта', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NFIN_IN', SCAPTION => 'Входящее финансирование', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SLNK_UNIT_NFIN_IN', SCAPTION => 'Входящее финансирование (код раздела ссылки)', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NLNK_DOCUMENT_NFIN_IN', SCAPTION => 'Входящее финансирование (документ ссылки)', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NFIN_OUT', SCAPTION => 'Исходящее финансирование', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SLNK_UNIT_NFIN_OUT', SCAPTION => 'Исходящее финансирование (код раздела ссылки)', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NLNK_DOCUMENT_NFIN_OUT', SCAPTION => 'Исходящее финансирование (документ ссылки)', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BVISIBLE => false); PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 0, BCLEAR => true); PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 1); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NCTRL_FIN', SCAPTION => 'Фин-е (исх.)', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, SCOND_FROM => 'EDCTRL_FIN', BORDER => true, BFILTER => true, RCOL_VALS => RCOL_VALS, SHINT => 'Финансирование (исходящее) - контроль оплаты счетов, выставленных соисполнителями в рамках проекта.
' || 'Требует внимания - в проекте есть этапы, для которых не все выставленные соисполнителями счета оплачены.
' || 'В норме - нет этапов с отклонениями, описанными выше.
' || 'Пусто - в Системе не хватает данных для рассчёта. Убедитесь, что для этапов задана привязка к договорам с соисполнителями.'); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NCTRL_CONTR', SCAPTION => 'Контр-я', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, SCOND_FROM => 'EDCTRL_CONTR', BORDER => true, BFILTER => true, RCOL_VALS => RCOL_VALS, SHINT => 'Контрактация - контроль суммы договоров, заключеных с соисполнителями в рамках проекта.
' || 'Требует внимания - в проекте есть этапы, для которых сумма договоров с соисполнителями превышает заложенные в калькуляцию плановые показатели.
' || 'В норме - нет этапов с отклонениями, описанными выше.
' || 'Пусто - в Системе не хватает данных для рассчёта. Убедитесь, что для всех этапов заданы плановые калькуляции.'); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NCTRL_COEXEC', SCAPTION => 'Соисп-е', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, SCOND_FROM => 'EDCTRL_COEXEC', BORDER => true, BFILTER => true, RCOL_VALS => RCOL_VALS, SHINT => 'Соисполнение - контроль исполнения обязательств по договорам, заключеным с соисполнителями в рамках проекта.
' || 'Требует внимания - в проекте есть этапы, до окончания которых осталось менее ' || TO_CHAR(NDAYS_LEFT_LIMIT) || ' дней, при этом зафиксирован положительный остаток к поставке/актированию по договорам соисполнителей данного этапа.
' || 'В норме - нет этапов с отклонениями, описанными выше.
' || 'Пусто - в Системе не хватает данных для рассчёта. Убедитесь, что для этапов задана привязка к договорам с соисполнителями и плановые сроки окончания.'); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NCTRL_PERIOD', SCAPTION => 'Сроки', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, SCOND_FROM => 'EDCTRL_PERIOD', BORDER => true, BFILTER => true, RCOL_VALS => RCOL_VALS, SHINT => 'Сроки - контроль сроков исполнения работ по проекту.
' || 'Требует внимания - в проекте есть этапы, до окончания которых осталось менее ' || TO_CHAR(NDAYS_LEFT_LIMIT) || ' дней.
' || 'В норме - нет этапов с отклонениями, описанными выше.
' || 'Пусто - в Системе не хватает данных для рассчёта. Убедитесь, что для этапов заданы плановые сроки окончания.'); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NCTRL_COST', SCAPTION => 'Затраты', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, SCOND_FROM => 'EDCTRL_COST', BORDER => true, BFILTER => true, RCOL_VALS => RCOL_VALS, SHINT => 'Затраты - контроль затрат, понесённых в ходе выполнения работ по проекту.
' || 'Требует внимания - в проекте есть этапы, для которых сумма фактических затрат по статьям калькуляции превысила плановую.
' || 'В норме - нет этапов с отклонениями, описанными выше.
' || 'Пусто - в Системе не хватает данных для рассчёта. Убедитесь, что для этапов задана действующая калькуляция с указанием плановых значений по статьям, подлежащим контролю.'); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NCTRL_ACT', SCAPTION => 'Актир-е', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, SCOND_FROM => 'EDCTRL_ACT', BORDER => true, BFILTER => true, RCOL_VALS => RCOL_VALS, SHINT => 'Актирование - контроль актирования работ, выполненных по проекту, со стороны заказчика.
' || 'Требует внимания - в проекте есть этапы, в состоянии "Закрыт", но при этом в Системе отсутствует утверждённая "Расходная накладная на отпуск потребителю" для данного этапа.
' || 'В норме - нет этапов с отклонениями, описанными выше.
' || 'Пусто - в Системе не хватает данных для рассчёта. Убедитесь, что этапы, по которым завершены работы, переведены в состояние "Закрыт".'); PKG_P8PANELS_VISUAL.TDATA_GRID_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 := 'select * from (select D.*, ROWNUM NROW from (select P.RN NRN, P.CODE SCODE, P.NAME SNAME, P.NAME_USL SNAME_USL, P.EXPECTED_RES SEXPECTED_RES, PT.CODE SPRJTYPE, EC.AGNABBR SEXT_CUST, GC.CODE SGOVCNTRID, P.DOC_OSN SDOC_OSN, ''Contracts'' SLNK_UNIT_SDOC_OSN, PKG_P8PANELS_PROJECTS.GET_DOC_OSN_LNK_DOCUMENT(P.RN) NLNK_DOCUMENT_SDOC_OSN, SR.CODE SSUBDIV_RESP, R.AGNABBR SRESPONSIBLE, F_DOCS_PROPS_GET_STR_VALUE(:NECON_RESP_DP, ''Projects'', P.RN) SECON_RESP, P.STATE NSTATE, P.BEGPLAN DBEGPLAN, P.ENDPLAN DENDPLAN, P.COST_SUM_BASECURR NCOST_SUM, CN.INTCODE SCURNAMES, PKG_P8PANELS_PROJECTS.GET_FIN_IN(P.RN) NFIN_IN, ''Paynotes'' SLNK_UNIT_NFIN_IN, 0 NLNK_DOCUMENT_NFIN_IN, PKG_P8PANELS_PROJECTS.GET_FIN_OUT(P.RN) NFIN_OUT, ''Paynotes'' SLNK_UNIT_NFIN_OUT, 1 NLNK_DOCUMENT_NFIN_OUT, PKG_P8PANELS_PROJECTS.GET_CTRL_FIN(P.RN) NCTRL_FIN, PKG_P8PANELS_PROJECTS.GET_CTRL_CONTR(P.RN) NCTRL_CONTR, PKG_P8PANELS_PROJECTS.GET_CTRL_COEXEC(P.RN) NCTRL_COEXEC, PKG_P8PANELS_PROJECTS.GET_CTRL_PERIOD(P.RN) NCTRL_PERIOD, PKG_P8PANELS_PROJECTS.GET_CTRL_COST(P.RN) NCTRL_COST, PKG_P8PANELS_PROJECTS.GET_CTRL_ACT(P.RN) NCTRL_ACT, PKG_P8PANELS_PROJECTS.GET_COST_READY(P.RN) NCOST_READY from PROJECT P, PRJTYPE PT, AGNLIST EC, GOVCNTRID GC, INS_DEPARTMENT SR, AGNLIST R, CURNAMES CN where P.PRJTYPE = PT.RN and P.EXT_CUST = EC.RN(+) and P.GOVCNTRID = GC.RN(+) and P.SUBDIV_RESP = SR.RN(+) and P.RESPONSIBLE = R.RN(+) and P.CURNAMES = CN.RN and 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'') and P.RN in (select ID from COND_BROKER_IDSMART where IDENT = :NIDENT) %ORDER_BY%) D) F where F.NROW between :NROW_FROM and :NROW_TO'; /* Учтём сортировки */ PKG_P8PANELS_VISUAL.TORDERS_SET_QUERY(RDATA_GRID => RDG, RORDERS => RO, SPATTERN => '%ORDER_BY%', CSQL => CSQL); /* Учтём фильтры */ PKG_P8PANELS_VISUAL.TFILTERS_SET_QUERY(NIDENT => NIDENT, NCOMPANY => NCOMPANY, SUNIT => 'Projects', SPROCEDURE => 'PKG_P8PANELS_PROJECTS.COND', RDATA_GRID => RDG, RFILTERS => RF); /* Разбираем его */ ICURSOR := PKG_SQL_DML.OPEN_CURSOR(SWHAT => 'SELECT'); PKG_SQL_DML.PARSE(ICURSOR => ICURSOR, SQUERY => CSQL); /* Делаем подстановку параметров */ PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NECON_RESP_DP', NVALUE => NECON_RESP_DP); PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NIDENT', NVALUE => NIDENT); PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NROW_FROM', NVALUE => NROW_FROM); PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NROW_TO', NVALUE => NROW_TO); /* Описываем структуру записи курсора */ PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 1); PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 2); PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 3); PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 4); PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 5); PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 6); PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 7); PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 8); PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 9); PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 10); PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 11); PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 12); PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 13); PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 14); PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 15); PKG_SQL_DML.DEFINE_COLUMN_DATE(ICURSOR => ICURSOR, IPOSITION => 16); PKG_SQL_DML.DEFINE_COLUMN_DATE(ICURSOR => ICURSOR, IPOSITION => 17); PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 18); PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 19); PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 20); PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 21); PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 22); PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 23); PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 24); PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 25); PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 26); PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 27); PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 28); PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 29); PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 30); PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 31); 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.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NRN', ICURSOR => ICURSOR, NPOSITION => 1, BCLEAR => true); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SCODE', ICURSOR => ICURSOR, NPOSITION => 2); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SNAME', ICURSOR => ICURSOR, NPOSITION => 3); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SNAME_USL', ICURSOR => ICURSOR, NPOSITION => 4); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SEXPECTED_RES', ICURSOR => ICURSOR, NPOSITION => 5); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SPRJTYPE', ICURSOR => ICURSOR, NPOSITION => 6); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SEXT_CUST', ICURSOR => ICURSOR, NPOSITION => 7); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SGOVCNTRID', ICURSOR => ICURSOR, NPOSITION => 8); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SDOC_OSN', ICURSOR => ICURSOR, NPOSITION => 9); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SLNK_UNIT_SDOC_OSN', ICURSOR => ICURSOR, NPOSITION => 10); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NLNK_DOCUMENT_SDOC_OSN', ICURSOR => ICURSOR, NPOSITION => 11); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SSUBDIV_RESP', ICURSOR => ICURSOR, NPOSITION => 12); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SRESPONSIBLE', ICURSOR => ICURSOR, NPOSITION => 13); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SECON_RESP', ICURSOR => ICURSOR, NPOSITION => 14); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NSTATE', ICURSOR => ICURSOR, NPOSITION => 15); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLD(RROW => RDG_ROW, SNAME => 'DBEGPLAN', ICURSOR => ICURSOR, NPOSITION => 16); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLD(RROW => RDG_ROW, SNAME => 'DENDPLAN', ICURSOR => ICURSOR, NPOSITION => 17); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NCOST_SUM', ICURSOR => ICURSOR, NPOSITION => 18); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SCURNAMES', ICURSOR => ICURSOR, NPOSITION => 19); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NFIN_IN', ICURSOR => ICURSOR, NPOSITION => 20); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SLNK_UNIT_NFIN_IN', ICURSOR => ICURSOR, NPOSITION => 21); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NLNK_DOCUMENT_NFIN_IN', ICURSOR => ICURSOR, NPOSITION => 22); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NFIN_OUT', ICURSOR => ICURSOR, NPOSITION => 23); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SLNK_UNIT_NFIN_OUT', ICURSOR => ICURSOR, NPOSITION => 24); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NLNK_DOCUMENT_NFIN_OUT', ICURSOR => ICURSOR, NPOSITION => 25); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NCTRL_FIN', ICURSOR => ICURSOR, NPOSITION => 26); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NCTRL_CONTR', ICURSOR => ICURSOR, NPOSITION => 27); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NCTRL_COEXEC', ICURSOR => ICURSOR, NPOSITION => 28); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NCTRL_PERIOD', ICURSOR => ICURSOR, NPOSITION => 29); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NCTRL_COST', ICURSOR => ICURSOR, NPOSITION => 30); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NCTRL_ACT', ICURSOR => ICURSOR, NPOSITION => 31); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NCOST_READY', ICURSOR => ICURSOR, NPOSITION => 32); /* Добавляем строку в таблицу */ PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW); end loop; /* Освобождаем курсор */ PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR); exception when others then PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR); raise; end; /* Сериализуем описание */ COUT := PKG_P8PANELS_VISUAL.TDATA_GRID_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => NINCLUDE_DEF); end LIST; /* График по данным проектов - "Топ проблем" */ 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 => NYEAR); PKG_P8PANELS_VISUAL.TCHART_DATASET_ITM_ATTR_VL_ADD(RATTR_VALS => RATTR_VALS, SNAME => 'NMONTH', SVALUE => 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_P8PANELS_PROJECTS.STAGES_GET_CTRL_FIN(RN) = :EDCTRL_FIN'); PKG_COND_BROKER.BIND_VARIABLE(SVARIABLE_NAME => 'EDCTRL_FIN', NVALUE => PKG_COND_BROKER.GET_CONDITION_NUM(SCONDITION_NAME => 'EDCTRL_FIN')); end if; /* Контроль контрактации */ if (PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'EDCTRL_CONTR') = 1) then PKG_COND_BROKER.ADD_CLAUSE(SCLAUSE => 'PKG_P8PANELS_PROJECTS.STAGES_GET_CTRL_CONTR(RN) = :EDCTRL_CONTR'); PKG_COND_BROKER.BIND_VARIABLE(SVARIABLE_NAME => 'EDCTRL_CONTR', NVALUE => PKG_COND_BROKER.GET_CONDITION_NUM(SCONDITION_NAME => 'EDCTRL_CONTR')); end if; /* Контроль соисполнения */ if (PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'EDCTRL_COEXEC') = 1) then PKG_COND_BROKER.ADD_CLAUSE(SCLAUSE => 'PKG_P8PANELS_PROJECTS.STAGES_GET_CTRL_COEXEC(RN) = :EDCTRL_COEXEC'); PKG_COND_BROKER.BIND_VARIABLE(SVARIABLE_NAME => 'EDCTRL_COEXEC', NVALUE => PKG_COND_BROKER.GET_CONDITION_NUM(SCONDITION_NAME => 'EDCTRL_COEXEC')); end if; /* Контроль сроков */ if (PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'EDCTRL_PERIOD') = 1) then PKG_COND_BROKER.ADD_CLAUSE(SCLAUSE => 'PKG_P8PANELS_PROJECTS.STAGES_GET_CTRL_PERIOD(RN) = :EDCTRL_PERIOD'); PKG_COND_BROKER.BIND_VARIABLE(SVARIABLE_NAME => 'EDCTRL_PERIOD', NVALUE => PKG_COND_BROKER.GET_CONDITION_NUM(SCONDITION_NAME => 'EDCTRL_PERIOD')); end if; /* Контроль затрат */ if (PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'EDCTRL_COST') = 1) then PKG_COND_BROKER.ADD_CLAUSE(SCLAUSE => 'PKG_P8PANELS_PROJECTS.STAGES_GET_CTRL_COST(RN) = :EDCTRL_COST'); PKG_COND_BROKER.BIND_VARIABLE(SVARIABLE_NAME => 'EDCTRL_COST', NVALUE => PKG_COND_BROKER.GET_CONDITION_NUM(SCONDITION_NAME => 'EDCTRL_COST')); end if; /* Контроль актирования */ if (PKG_COND_BROKER.CONDITION_EXISTS(SCONDITION_NAME => 'EDCTRL_ACT') = 1) then PKG_COND_BROKER.ADD_CLAUSE(SCLAUSE => '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_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_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_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 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.TFILTERS; -- Фильтры RO PKG_P8PANELS_VISUAL.TORDERS; -- Сортировки RDG PKG_P8PANELS_VISUAL.TDATA_GRID; -- Описание таблицы RDG_ROW PKG_P8PANELS_VISUAL.TROW; -- Строка таблицы RCOL_VALS PKG_P8PANELS_VISUAL.TCOL_VALS; -- Предопределённые значения столбцов NROW_FROM PKG_STD.TREF; -- Номер строки с NROW_TO PKG_STD.TREF; -- Номер строки по NFPDARTCL_REALIZ PKG_STD.TREF; -- Рег. номер статьи калькуляции для реализации CSQL clob; -- Буфер для запроса ICURSOR integer; -- Курсор для исполнения запроса NCOST_FACT PKG_STD.TNUMBER; -- Сумма фактических затрат по этапу проекта NSUMM_REALIZ PKG_STD.TNUMBER; -- Сумма реализации по этапу проекта NSUMM_INCOME PKG_STD.TNUMBER; -- Сумма прибыли по этапу проекта NINCOME_PRC PKG_STD.TNUMBER; -- Процент прибыли по этапу проекта begin /* Определим рег. номер статьи калькуляции для учёта реализации */ FIND_FPDARTCL_CODE(NFLAG_SMART => 1, NCOMPANY => NCOMPANY, SCODE => SFPDARTCL_REALIZ, NRN => NFPDARTCL_REALIZ); /* Читаем фильтры */ RF := PKG_P8PANELS_VISUAL.TFILTERS_FROM_XML(CFILTERS => CFILTERS); /* Читем сортировки */ RO := PKG_P8PANELS_VISUAL.TORDERS_FROM_XML(CORDERS => CORDERS); /* Преобразуем номер и размер страницы в номер строк с и по */ PKG_P8PANELS_VISUAL.UTL_ROWS_LIMITS_CALC(NPAGE_NUMBER => NPAGE_NUMBER, NPAGE_SIZE => NPAGE_SIZE, NROW_FROM => NROW_FROM, NROW_TO => NROW_TO); /* Инициализируем таблицу данных */ RDG := PKG_P8PANELS_VISUAL.TDATA_GRID_MAKE(); /* Добавляем в таблицу описание колонок */ PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NRN', SCAPTION => 'Рег. номер', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SNUMB', SCAPTION => 'Номер', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, SCOND_FROM => 'EDNUMB', BORDER => true, BFILTER => true); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SNAME', SCAPTION => 'Наименование', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, SCOND_FROM => 'EDNAME', BORDER => true, BFILTER => true); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SEXPECTED_RES', SCAPTION => 'Ожидаемые результаты', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SFACEACC', SCAPTION => 'Шифр затрат', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, BVISIBLE => false); PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 0, BCLEAR => true); PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 1); PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 2); PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 3); PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 4); PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 5); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NSTATE', SCAPTION => 'Состояние', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, SCOND_FROM => 'CGSTATE', BORDER => true, BFILTER => true, RCOL_VALS => RCOL_VALS); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'DBEGPLAN', SCAPTION => 'Дата начала', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_DATE, SCOND_FROM => 'EDPLANBEGFrom', SCOND_TO => 'EDPLANBEGTo', BORDER => true, BFILTER => true); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'DENDPLAN', SCAPTION => 'Дата окончания', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_DATE, SCOND_FROM => 'EDPLANENDFrom', SCOND_TO => 'EDPLANENDTo', BORDER => true, BFILTER => true); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NCOST_SUM', SCAPTION => 'Стоимость', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SCURNAMES', SCAPTION => 'Валюта', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NFIN_IN', SCAPTION => 'Входящее финансирование', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SLNK_UNIT_NFIN_IN', SCAPTION => 'Входящее финансирование (код раздела ссылки)', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NLNK_DOCUMENT_NFIN_IN', SCAPTION => 'Входящее финансирование (документ ссылки)', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NFIN_OUT', SCAPTION => 'Исходящее финансирование', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SLNK_UNIT_NFIN_OUT', SCAPTION => 'Исходящее финансирование (код раздела ссылки)', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NLNK_DOCUMENT_NFIN_OUT', SCAPTION => 'Исходящее финансирование (документ ссылки)', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BVISIBLE => false); PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 0, BCLEAR => true); PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 1); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NCTRL_FIN', SCAPTION => 'Фин-е (исх.)', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, SCOND_FROM => 'EDCTRL_FIN', BORDER => true, BFILTER => true, RCOL_VALS => RCOL_VALS, SHINT => 'Финансирование (исходящее) - контроль оплаты счетов, выставленных соисполнителями по этапу.
' || 'Требует внимания - к этапу привязаны договоры соисполнителей, для которых не все выставленные соисполнителями счета оплачены.
' || 'В норме - нет договоров соисполнения с отклонениями, описанными выше.
' || 'Пусто - в Системе не хватает данных для рассчёта. Убедитесь, что для этапов задана привязка к договорам с соисполнителями.'); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NCTRL_CONTR', SCAPTION => 'Контр-я', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, SCOND_FROM => 'EDCTRL_CONTR', BORDER => true, BFILTER => true, RCOL_VALS => RCOL_VALS, SHINT => 'Контрактация - контроль суммы договоров, заключеных с соисполнителями в рамках этапа.
' || 'Требует внимания - сумма договоров с соисполнителями, привязанных к этапу, превышает заложенные в калькуляцию плановые показатели по сответствующим статьям.
' || 'В норме - нет описанных выше отклонений.
' || 'Пусто - в Системе не хватает данных для рассчёта. Убедитесь, что для этапа задана калькуляция и для контрагентских статей указаны плановые показатели.'); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NCTRL_COEXEC', SCAPTION => 'Соисп-е', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, SCOND_FROM => 'EDCTRL_COEXEC', BORDER => true, BFILTER => true, RCOL_VALS => RCOL_VALS, SHINT => 'Соисполнение - контроль исполнения обязательств по договорам, заключеным с соисполнителями в рамках этапа.
' || 'Требует внимания - до окончания этапа осталось менее ' || TO_CHAR(NDAYS_LEFT_LIMIT) || ' дней, при этом зафиксирован положительный остаток к поставке/актированию по привязанным к нему договорам соисполнителей.
' || 'В норме - нет описанных выше отклонений.
' || 'Пусто - в Системе не хватает данных для рассчёта. Убедитесь, что для этапа задана привязка к договорам с соисполнителями и плановый срок окончания.'); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NDAYS_LEFT', SCAPTION => 'Дней до окончания', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NCTRL_PERIOD', SCAPTION => 'Сроки', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, SCOND_FROM => 'EDCTRL_PERIOD', BORDER => true, BFILTER => true, RCOL_VALS => RCOL_VALS, SHINT => 'Сроки - контроль сроков исполнения работ по этапу.
' || 'Требует внимания - до окончания этапа осталось менее ' || TO_CHAR(NDAYS_LEFT_LIMIT) || ' дней.
' || 'В норме - нет описанных выше отклонений.
' || 'Пусто - в Системе не хватает данных для рассчёта. Убедитесь, что для этапа задан плановый срок окончания.'); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NCOST_FACT', SCAPTION => 'Сумма фактических затрат', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SLNK_UNIT_NCOST_FACT', SCAPTION => 'Сумма фактических затрат (код раздела ссылки)', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NLNK_DOCUMENT_NCOST_FACT', SCAPTION => 'Сумма фактических затрат (документ ссылки)', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NSUMM_REALIZ', SCAPTION => 'Сумма реализации', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SLNK_UNIT_NSUMM_REALIZ', SCAPTION => 'Сумма реализации (код раздела ссылки)', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NLNK_DOCUMENT_NSUMM_REALIZ', SCAPTION => 'Сумма реализации (документ ссылки)', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NSUMM_INCOME', SCAPTION => 'Сумма прибыли', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NINCOME_PRC', SCAPTION => 'Процент прибыли', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NCTRL_COST', SCAPTION => 'Затраты', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, SCOND_FROM => 'EDCTRL_COST', BORDER => true, BFILTER => true, RCOL_VALS => RCOL_VALS, SHINT => 'Затраты - контроль затрат, понесённых в ходе выполнения работ по этапу.
' || 'Требует внимания - сумма фактических затрат этапа по некоторым статьям калькуляции превысила плановую.
' || 'В норме - нет описанных выше отклонений.
' || 'Пусто - в Системе не хватает данных для рассчёта. Убедитесь, что для этапа задана действующая калькуляция с указанием плановых значений по статьям, подлежащим контролю.'); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NCTRL_ACT', SCAPTION => 'Актир-е', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, SCOND_FROM => 'EDCTRL_ACT', BORDER => true, BFILTER => true, RCOL_VALS => RCOL_VALS, SHINT => 'Актирование - контроль актирования работ, выполненных по этапу, со стороны заказчика.
' || 'Требует внимания - этап в состоянии "Закрыт", но при этом в Системе отсутствует утверждённая "Расходная накладная на отпуск потребителю" для данного этапа.
' || 'В норме - нет описанных выше отклонений.
' || 'Пусто - в Системе не хватает данных для рассчёта. Убедитесь, что этап, если работы по нему завершены, переведен в состояние "Закрыт".'); PKG_P8PANELS_VISUAL.TDATA_GRID_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); /* Обходим данные */ begin /* Собираем запрос */ CSQL := 'select * from (select D.*, ROWNUM NROW from (select PS.RN NRN, PS.NUMB SNUMB, PS.NAME SNAME, PS.EXPECTED_RES SEXPECTED_RES, FAC.NUMB SFACEACC, PS.STATE NSTATE, PS.BEGPLAN DBEGPLAN, PS.ENDPLAN DENDPLAN, PS.COST_SUM_BASECURR NCOST_SUM, CN.INTCODE SCURNAMES, PKG_P8PANELS_PROJECTS.STAGES_GET_FIN_IN(PS.RN) NFIN_IN, ''Paynotes'' SLNK_UNIT_NFIN_IN, 0 NLNK_DOCUMENT_NFIN_IN, PKG_P8PANELS_PROJECTS.STAGES_GET_FIN_OUT(PS.RN) NFIN_OUT, ''Paynotes'' SLNK_UNIT_NFIN_OUT, 1 NLNK_DOCUMENT_NFIN_OUT, PKG_P8PANELS_PROJECTS.STAGES_GET_CTRL_FIN(PS.RN) NCTRL_FIN, PKG_P8PANELS_PROJECTS.STAGES_GET_CTRL_CONTR(PS.RN) NCTRL_CONTR, PKG_P8PANELS_PROJECTS.STAGES_GET_CTRL_COEXEC(PS.RN) NCTRL_COEXEC, PKG_P8PANELS_PROJECTS.STAGES_GET_DAYS_LEFT(PS.RN) NDAYS_LEFT, PKG_P8PANELS_PROJECTS.STAGES_GET_CTRL_PERIOD(PS.RN) NCTRL_PERIOD, PKG_P8PANELS_PROJECTS.STAGES_GET_COST_FACT(PS.RN) NCOST_FACT, ''CostNotes'' SLNK_UNIT_NCOST_FACT, 1 NLNK_DOCUMENT_NCOST_FACT, PKG_P8PANELS_PROJECTS.STAGES_GET_SUMM_REALIZ(PS.RN, :NFPDARTCL_REALIZ) NSUMM_REALIZ, ''GoodsTransInvoicesToConsumers'' SLNK_UNIT_NSUMM_REALIZ, 1 NLNK_DOCUMENT_NSUMM_REALIZ, PKG_P8PANELS_PROJECTS.STAGES_GET_CTRL_COST(PS.RN) NCTRL_COST, PKG_P8PANELS_PROJECTS.STAGES_GET_CTRL_ACT(PS.RN) NCTRL_ACT, PKG_P8PANELS_PROJECTS.STAGES_GET_COST_READY(PS.RN) NCOST_READY from PROJECTSTAGE PS, PROJECT P, FACEACC FAC, CURNAMES CN where PS.PRN = P.RN and PS.FACEACC = FAC.RN(+) and P.CURNAMES = CN.RN and 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 PS.RN in (select ID from COND_BROKER_IDSMART where IDENT = :NIDENT) %ORDER_BY%) D) F where F.NROW between :NROW_FROM and :NROW_TO'; /* Учтём сортировки */ PKG_P8PANELS_VISUAL.TORDERS_SET_QUERY(RDATA_GRID => RDG, RORDERS => RO, SPATTERN => '%ORDER_BY%', CSQL => CSQL); /* Учтём фильтры */ PKG_P8PANELS_VISUAL.TFILTERS_SET_QUERY(NIDENT => NIDENT, NCOMPANY => NCOMPANY, NPARENT => NPRN, SUNIT => 'ProjectsStages', SPROCEDURE => 'PKG_P8PANELS_PROJECTS.STAGES_COND', RDATA_GRID => RDG, RFILTERS => RF); /* Разбираем его */ ICURSOR := PKG_SQL_DML.OPEN_CURSOR(SWHAT => 'SELECT'); PKG_SQL_DML.PARSE(ICURSOR => ICURSOR, SQUERY => CSQL); /* Делаем подстановку параметров */ PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NIDENT', NVALUE => NIDENT); PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NROW_FROM', NVALUE => NROW_FROM); PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NROW_TO', NVALUE => NROW_TO); PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NFPDARTCL_REALIZ', NVALUE => NFPDARTCL_REALIZ); /* Описываем структуру записи курсора */ PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 1); PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 2); PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 3); PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 4); PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 5); PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 6); PKG_SQL_DML.DEFINE_COLUMN_DATE(ICURSOR => ICURSOR, IPOSITION => 7); PKG_SQL_DML.DEFINE_COLUMN_DATE(ICURSOR => ICURSOR, IPOSITION => 8); PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 9); PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 10); PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 11); PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 12); PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 13); PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 14); PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 15); PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 16); PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 17); PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 18); PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 19); PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 20); PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 21); PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 22); PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 23); PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 24); PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 25); PKG_SQL_DML.DEFINE_COLUMN_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); /* Делаем выборку */ if (PKG_SQL_DML.EXECUTE(ICURSOR => ICURSOR) = 0) then null; end if; /* Обходим выбранные записи */ while (PKG_SQL_DML.FETCH_ROWS(ICURSOR => ICURSOR) > 0) loop /* Добавляем колонки с данными */ PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NRN', ICURSOR => ICURSOR, NPOSITION => 1, BCLEAR => true); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SNUMB', ICURSOR => ICURSOR, NPOSITION => 2); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SNAME', ICURSOR => ICURSOR, NPOSITION => 3); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SEXPECTED_RES', ICURSOR => ICURSOR, NPOSITION => 4); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SFACEACC', ICURSOR => ICURSOR, NPOSITION => 5); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NSTATE', ICURSOR => ICURSOR, NPOSITION => 6); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLD(RROW => RDG_ROW, SNAME => 'DBEGPLAN', ICURSOR => ICURSOR, NPOSITION => 7); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLD(RROW => RDG_ROW, SNAME => 'DENDPLAN', ICURSOR => ICURSOR, NPOSITION => 8); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NCOST_SUM', ICURSOR => ICURSOR, NPOSITION => 9); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SCURNAMES', ICURSOR => ICURSOR, NPOSITION => 10); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NFIN_IN', ICURSOR => ICURSOR, NPOSITION => 11); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SLNK_UNIT_NFIN_IN', ICURSOR => ICURSOR, NPOSITION => 12); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NLNK_DOCUMENT_NFIN_IN', ICURSOR => ICURSOR, NPOSITION => 13); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NFIN_OUT', ICURSOR => ICURSOR, NPOSITION => 14); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SLNK_UNIT_NFIN_OUT', ICURSOR => ICURSOR, NPOSITION => 15); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NLNK_DOCUMENT_NFIN_OUT', ICURSOR => ICURSOR, NPOSITION => 16); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NCTRL_FIN', ICURSOR => ICURSOR, NPOSITION => 17); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NCTRL_CONTR', ICURSOR => ICURSOR, NPOSITION => 18); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NCTRL_COEXEC', ICURSOR => ICURSOR, NPOSITION => 19); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NDAYS_LEFT', ICURSOR => ICURSOR, NPOSITION => 20); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NCTRL_PERIOD', ICURSOR => ICURSOR, NPOSITION => 21); PKG_SQL_DML.COLUMN_VALUE_NUM(ICURSOR => ICURSOR, IPOSITION => 22, NVALUE => NCOST_FACT); PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NCOST_FACT', NVALUE => NCOST_FACT); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SLNK_UNIT_NCOST_FACT', ICURSOR => ICURSOR, NPOSITION => 23); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NLNK_DOCUMENT_NCOST_FACT', ICURSOR => ICURSOR, NPOSITION => 24); PKG_SQL_DML.COLUMN_VALUE_NUM(ICURSOR => ICURSOR, IPOSITION => 25, NVALUE => NSUMM_REALIZ); if (NSUMM_REALIZ = 0) then NSUMM_INCOME := 0; NINCOME_PRC := 0; else NSUMM_INCOME := NSUMM_REALIZ - NCOST_FACT; NINCOME_PRC := NSUMM_INCOME / NCOST_FACT * 100; end if; PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NSUMM_REALIZ', NVALUE => NSUMM_REALIZ); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SLNK_UNIT_NSUMM_REALIZ', ICURSOR => ICURSOR, NPOSITION => 26); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NLNK_DOCUMENT_NSUMM_REALIZ', ICURSOR => ICURSOR, NPOSITION => 27); PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NSUMM_INCOME', NVALUE => NSUMM_INCOME); PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NINCOME_PRC', NVALUE => NINCOME_PRC); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NCTRL_COST', ICURSOR => ICURSOR, NPOSITION => 28); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NCTRL_ACT', ICURSOR => ICURSOR, NPOSITION => 29); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NCOST_READY', ICURSOR => ICURSOR, NPOSITION => 30); /* Добавляем строку в таблицу */ PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW); end loop; /* Освобождаем курсор */ PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR); exception when others then PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR); raise; end; /* Сериализуем описание */ COUT := PKG_P8PANELS_VISUAL.TDATA_GRID_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => NINCLUDE_DEF); end STAGES_LIST; /* Подбор записей журнала затрат по статье калькуляции этапа проекта */ 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.TFILTERS; -- Фильтры RF_CTRL_COST PKG_P8PANELS_VISUAL.TFILTER; -- Фильтр по колонке "Контроль (затраты)" NCTRL_COST_FROM PKG_STD.TNUMBER; -- Нижняя граница диапазона фильтра по колонке "Контроль (затраты)" NCTRL_COST_TO PKG_STD.TNUMBER; -- Верхняя граница диапазона фильтра по колонке "Контроль (затраты)" RF_CTRL_CONTR PKG_P8PANELS_VISUAL.TFILTER; -- Фильтр по колонке "Контроль (контрактация)" NCTRL_CONTR_FROM PKG_STD.TNUMBER; -- Нижняя граница диапазона фильтра по колонке "Контроль (контрактация)" NCTRL_CONTR_TO PKG_STD.TNUMBER; -- Верхняя граница диапазона фильтра по колонке "Контроль (контрактация)" RDG PKG_P8PANELS_VISUAL.TDATA_GRID; -- Описание таблицы RDG_ROW PKG_P8PANELS_VISUAL.TROW; -- Строка таблицы RCOL_VALS PKG_P8PANELS_VISUAL.TCOL_VALS; -- Предопределённые значения столбцов RSTAGE_ARTS TSTAGE_ARTS; -- Список статей этапа проекта begin /* Читаем фильтры */ RF := PKG_P8PANELS_VISUAL.TFILTERS_FROM_XML(CFILTERS => CFILTERS); /* Найдем фильтр по контролю затрат */ RF_CTRL_COST := PKG_P8PANELS_VISUAL.TFILTERS_FIND(RFILTERS => RF, SNAME => 'NCTRL_COST'); PKG_P8PANELS_VISUAL.TFILTER_TO_NUMBER(RFILTER => RF_CTRL_COST, NFROM => NCTRL_COST_FROM, NTO => NCTRL_COST_TO); /* Найдем фильтр по контролю контрактации */ RF_CTRL_CONTR := PKG_P8PANELS_VISUAL.TFILTERS_FIND(RFILTERS => RF, SNAME => 'NCTRL_CONTR'); PKG_P8PANELS_VISUAL.TFILTER_TO_NUMBER(RFILTER => RF_CTRL_CONTR, NFROM => NCTRL_CONTR_FROM, NTO => NCTRL_CONTR_TO); /* Инициализируем таблицу данных */ RDG := PKG_P8PANELS_VISUAL.TDATA_GRID_MAKE(); /* Добавляем в таблицу описание колонок */ PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NRN', SCAPTION => 'Рег. номер', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SNUMB', SCAPTION => 'Номер', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SNAME', SCAPTION => 'Наименование статьи', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NPLAN', SCAPTION => 'План', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NCOST_FACT', SCAPTION => 'Фактические затраты', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NCOST_DIFF', SCAPTION => 'Отклонение по затратам', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BVISIBLE => false); PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 0, BCLEAR => true); PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 1); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NCTRL_COST', SCAPTION => 'Контроль (затраты)', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BFILTER => true, RCOL_VALS => RCOL_VALS); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NCONTR', SCAPTION => 'Законтрактовано', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NCONTR_LEFT', SCAPTION => 'Осталось законтрактовать', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NCTRL_CONTR', SCAPTION => 'Контроль (контрактация)', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BFILTER => true, RCOL_VALS => RCOL_VALS); /* Сформируем сведения по статям этапа проекта */ STAGE_ARTS_GET(NSTAGE => NSTAGE, NINC_COST => 1, NINC_CONTR => 1, RSTAGE_ARTS => RSTAGE_ARTS); /* Обходим собранные статьи */ if ((RSTAGE_ARTS is not null) and (RSTAGE_ARTS.COUNT > 0)) then for I in RSTAGE_ARTS.FIRST .. RSTAGE_ARTS.LAST loop /* Если прошли фильтр */ if (((NCTRL_COST_FROM is null) or ((NCTRL_COST_FROM is not null) and (NCTRL_COST_FROM = RSTAGE_ARTS(I).NCTRL_COST))) and ((NCTRL_CONTR_FROM is null) or ((NCTRL_CONTR_FROM is not null) and (NCTRL_CONTR_FROM = RSTAGE_ARTS(I).NCTRL_CONTR)))) then /* Добавляем колонки с данными */ PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NRN', NVALUE => RSTAGE_ARTS(I).NRN, BCLEAR => true); PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SNUMB', SVALUE => RSTAGE_ARTS(I).SCODE); PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SNAME', SVALUE => RSTAGE_ARTS(I).SNAME); PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NPLAN', NVALUE => RSTAGE_ARTS(I).NPLAN); PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NCOST_FACT', NVALUE => RSTAGE_ARTS(I).NCOST_FACT); PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NCOST_DIFF', NVALUE => RSTAGE_ARTS(I).NCOST_DIFF); PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NCTRL_COST', NVALUE => RSTAGE_ARTS(I).NCTRL_COST); PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NCONTR', NVALUE => RSTAGE_ARTS(I).NCONTR); PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NCONTR_LEFT', NVALUE => RSTAGE_ARTS(I).NCONTR_LEFT); PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NCTRL_CONTR', NVALUE => RSTAGE_ARTS(I).NCTRL_CONTR); /* Добавляем строку в таблицу */ PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW); end if; end loop; end if; /* Сериализуем описание */ COUT := PKG_P8PANELS_VISUAL.TDATA_GRID_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => NINCLUDE_DEF); end STAGE_ARTS_LIST; /* Считывание записи соисполнителя этапа проекта */ 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_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_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.TFILTERS; -- Фильтры RO PKG_P8PANELS_VISUAL.TORDERS; -- Сортировки RDG PKG_P8PANELS_VISUAL.TDATA_GRID; -- Описание таблицы RDG_ROW PKG_P8PANELS_VISUAL.TROW; -- Строка таблицы RCOL_VALS PKG_P8PANELS_VISUAL.TCOL_VALS; -- Предопределённые значения столбцов NROW_FROM PKG_STD.TREF; -- Номер строки с NROW_TO PKG_STD.TREF; -- Номер строки по CSQL clob; -- Буфер для запроса ICURSOR integer; -- Курсор для исполнения запроса 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.TFILTERS_FROM_XML(CFILTERS => CFILTERS); /* Читем сортировки */ RO := PKG_P8PANELS_VISUAL.TORDERS_FROM_XML(CORDERS => CORDERS); /* Преобразуем номер и размер страницы в номер строк с и по */ PKG_P8PANELS_VISUAL.UTL_ROWS_LIMITS_CALC(NPAGE_NUMBER => NPAGE_NUMBER, NPAGE_SIZE => NPAGE_SIZE, NROW_FROM => NROW_FROM, NROW_TO => NROW_TO); /* Инициализируем таблицу данных */ RDG := PKG_P8PANELS_VISUAL.TDATA_GRID_MAKE(); /* Добавляем в таблицу описание колонок */ PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NRN', SCAPTION => 'Рег. номер', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SDOC_PREF', SCAPTION => 'Префикс', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, SCOND_FROM => 'EDDOC_PREF', BORDER => true, BFILTER => true); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SLNK_UNIT_SDOC_PREF', SCAPTION => 'Префикс (код раздела ссылки)', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NLNK_DOCUMENT_SDOC_PREF', SCAPTION => 'Префикс (документ ссылки)', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SDOC_NUMB', SCAPTION => 'Номер', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, SCOND_FROM => 'EDDOC_NUMB', BORDER => true, BFILTER => true); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SLNK_UNIT_SDOC_NUMB', SCAPTION => 'Номер (код раздела ссылки)', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NLNK_DOCUMENT_SDOC_NUMB', SCAPTION => 'Номер (документ ссылки)', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'DDOC_DATE', SCAPTION => 'Дата', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_DATE, SCOND_FROM => 'EDDOC_DATEFrom', SCOND_TO => 'EDDOC_DATETo', BORDER => true, BFILTER => true); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SEXT_NUMBER', SCAPTION => 'Внешний номер', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SAGENT', SCAPTION => 'Соисполнитель', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, SCOND_FROM => 'EDAGENT', BORDER => true, BFILTER => true); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SAGENT_INN', SCAPTION => 'ИНН соисполнителя', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SAGENT_KPP', SCAPTION => 'КПП соисполнителя', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SGOVCNTRID', SCAPTION => 'ИГК', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SCSTAGE', SCAPTION => 'Этап', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, SCOND_FROM => 'EDSTAGE', BORDER => true, BFILTER => true); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SCSTAGE_DESCRIPTION', SCAPTION => 'Описание этапа', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'DCSTAGE_BEGIN_DATE', SCAPTION => 'Дата начала', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_DATE, SCOND_FROM => 'EDCSTAGE_BEGIN_DATEFrom', SCOND_TO => 'EDCSTAGE_BEGIN_DATETo', BORDER => true, BFILTER => true); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'DCSTAGE_END_DATE', SCAPTION => 'Дата окончания', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_DATE, SCOND_FROM => 'EDCSTAGE_END_DATEFrom', SCOND_TO => 'EDCSTAGE_END_DATETo', BORDER => true, BFILTER => true); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NSUMM', SCAPTION => 'Сумма', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SCURR', SCAPTION => 'Валюта', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SCOST_ART', SCAPTION => 'Статья затрат', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, SCOND_FROM => 'EDSCOST_ART', BORDER => true, BFILTER => true); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NPAY_IN', SCAPTION => 'Акцептовано счетов на оплату', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NFIN_OUT', SCAPTION => 'Оплачено счетов', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NPAY_IN_REST', SCAPTION => 'Осталось оплатить счетов', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BVISIBLE => false); PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 0, BCLEAR => true); PKG_P8PANELS_VISUAL.TCOL_VALS_ADD(RCOL_VALS => RCOL_VALS, NVALUE => 1); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NCTRL_FIN', SCAPTION => 'Фин-е (исх.)', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, SCOND_FROM => 'EDCTRL_FIN', BORDER => false, BFILTER => true, RCOL_VALS => RCOL_VALS, SHINT => 'Финансирование (исходящее) - контроль оплаты счетов, выставленных соисполнителем в рамках договора.
' || 'Требует внимания - не все выставленные соисполнителем акцептованные счета оплачены.
' || 'В норме - нет описанных выше отклонений.
' || 'Пусто - в Системе не хватает данных для рассчёта. Убедитесь, что для договора с соисполнителем аккуратно ведётся учёт первичных документов оперативного учёта (входящих счетов на оплату).'); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NFIN_REST', SCAPTION => 'Общий остаток к оплате по договору', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NCOEXEC_IN', SCAPTION => 'Получено актов/накладных', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NCOEXEC_REST', SCAPTION => 'Остаток к актированию/поставке', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NCTRL_COEXEC', SCAPTION => 'Соисполнение', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, SCOND_FROM => 'EDCTRL_COEXEC', BORDER => false, BFILTER => true, RCOL_VALS => RCOL_VALS, SHINT => 'Соисполнение - контроль исполнения обязательств по договору с соисполнителем.
' || 'Требует внимания - до окончания этапа проекта, в рамках которого действует соисполнение, осталось менее ' || TO_CHAR(NDAYS_LEFT_LIMIT) || ' дней, при этом зафиксирован положительный остаток к поставке/актированию по договору.
' || 'В норме - нет описанных выше отклонений.
' || 'Пусто - в Системе не хватает данных для рассчёта. Убедитесь, что для связанного этапа проекта задана плановая дата окончания, ' || 'а по договору с соисполнителем аккуратно ведётся учёт первичных документов оперативного учёта (приходных накладных).'); /* Обходим данные */ begin /* Собираем запрос */ CSQL := 'select * from (select D.*, ROWNUM NROW from (select PSPF.RN NRN, trim(CN.DOC_PREF) SDOC_PREF, ''Contracts'' SLNK_UNIT_SDOC_PREF, CN.RN NLNK_DOCUMENT_SDOC_PREF, trim(CN.DOC_NUMB) SDOC_NUMB, ''Contracts'' SLNK_UNIT_SDOC_NUMB, CN.RN NLNK_DOCUMENT_SDOC_NUMB, CN.DOC_DATE DDOC_DATE, CN.EXT_NUMBER SEXT_NUMBER, AG.AGNNAME SAGENT, AG.AGNIDNUMB SAGENT_INN, AG.REASON_CODE SAGENT_KPP, GC.CODE SGOVCNTRID, trim(ST.NUMB) SCSTAGE, ST.DESCRIPTION SCSTAGE_DESCRIPTION, ST.BEGIN_DATE DCSTAGE_BEGIN_DATE, ST.END_DATE DCSTAGE_END_DATE, PSPF.COST_PLAN NSUMM, CUR.INTCODE SCURR, ART.CODE SCOST_ART from PROJECTSTAGEPF PSPF, STAGES ST, CONTRACTS CN, AGNLIST AG, CURNAMES CUR, FPDARTCL ART, GOVCNTRID GC where PSPF.FACEACC = ST.FACEACC and ST.PRN = CN.RN and PSPF.PERFORMER = AG.RN and CN.CURRENCY = CUR.RN and PSPF.COST_ARTICLE = ART.RN(+) and CN.GOVCNTRID = GC.RN(+) and 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 = ST.CRN) and exists (select null from V_USERPRIV UP where UP.JUR_PERS = ST.JUR_PERS and UP.UNITCODE = ''Contracts'') and PSPF.RN in (select ID from COND_BROKER_IDSMART where IDENT = :NIDENT) %ORDER_BY%) D) F where F.NROW between :NROW_FROM and :NROW_TO'; /* Учтём сортировки */ PKG_P8PANELS_VISUAL.TORDERS_SET_QUERY(RDATA_GRID => RDG, RORDERS => RO, SPATTERN => '%ORDER_BY%', CSQL => CSQL); /* Учтём фильтры */ PKG_P8PANELS_VISUAL.TFILTERS_SET_QUERY(NIDENT => NIDENT, NCOMPANY => NCOMPANY, NPARENT => NSTAGE, SUNIT => 'ProjectsStagesPerformers', SPROCEDURE => 'PKG_P8PANELS_PROJECTS.STAGE_CONTRACTS_COND', RDATA_GRID => RDG, RFILTERS => RF); /* Разбираем его */ ICURSOR := PKG_SQL_DML.OPEN_CURSOR(SWHAT => 'SELECT'); PKG_SQL_DML.PARSE(ICURSOR => ICURSOR, SQUERY => CSQL); /* Делаем подстановку параметров */ PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NIDENT', NVALUE => NIDENT); PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NROW_FROM', NVALUE => NROW_FROM); PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NROW_TO', NVALUE => NROW_TO); /* Описываем структуру записи курсора */ PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 1); PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 2); PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 3); PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 4); PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 5); PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 6); PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 7); PKG_SQL_DML.DEFINE_COLUMN_DATE(ICURSOR => ICURSOR, IPOSITION => 8); PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 9); PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 10); PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 11); PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 12); PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 13); PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 14); PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 15); PKG_SQL_DML.DEFINE_COLUMN_DATE(ICURSOR => ICURSOR, IPOSITION => 16); PKG_SQL_DML.DEFINE_COLUMN_DATE(ICURSOR => ICURSOR, IPOSITION => 17); PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 18); PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 19); PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 20); /* Делаем выборку */ if (PKG_SQL_DML.EXECUTE(ICURSOR => ICURSOR) = 0) then null; end if; /* Обходим выбранные записи */ while (PKG_SQL_DML.FETCH_ROWS(ICURSOR => ICURSOR) > 0) loop /* Добавляем колонки с данными */ PKG_SQL_DML.COLUMN_VALUE_NUM(ICURSOR => ICURSOR, IPOSITION => 1, NVALUE => NPROJECTSTAGEPF); PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NRN', NVALUE => NPROJECTSTAGEPF, BCLEAR => true); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SDOC_PREF', ICURSOR => ICURSOR, NPOSITION => 2); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SLNK_UNIT_SDOC_PREF', ICURSOR => ICURSOR, NPOSITION => 3); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NLNK_DOCUMENT_SDOC_PREF', ICURSOR => ICURSOR, NPOSITION => 4); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SDOC_NUMB', ICURSOR => ICURSOR, NPOSITION => 5); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SLNK_UNIT_SDOC_NUMB', ICURSOR => ICURSOR, NPOSITION => 6); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NLNK_DOCUMENT_SDOC_NUMB', ICURSOR => ICURSOR, NPOSITION => 7); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLD(RROW => RDG_ROW, SNAME => 'DDOC_DATE', ICURSOR => ICURSOR, NPOSITION => 8); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SEXT_NUMBER', ICURSOR => ICURSOR, NPOSITION => 9); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SAGENT', ICURSOR => ICURSOR, NPOSITION => 10); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SAGENT_INN', ICURSOR => ICURSOR, NPOSITION => 11); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SAGENT_KPP', ICURSOR => ICURSOR, NPOSITION => 12); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SGOVCNTRID', ICURSOR => ICURSOR, NPOSITION => 13); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SCSTAGE', ICURSOR => ICURSOR, NPOSITION => 14); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SCSTAGE_DESCRIPTION', ICURSOR => ICURSOR, NPOSITION => 15); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLD(RROW => RDG_ROW, SNAME => 'DCSTAGE_BEGIN_DATE', ICURSOR => ICURSOR, NPOSITION => 16); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLD(RROW => RDG_ROW, SNAME => 'DCSTAGE_END_DATE', ICURSOR => ICURSOR, NPOSITION => 17); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NSUMM', ICURSOR => ICURSOR, NPOSITION => 18); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SCURR', ICURSOR => ICURSOR, NPOSITION => 19); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SCOST_ART', ICURSOR => ICURSOR, NPOSITION => 20); 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.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NPAY_IN', NVALUE => NPAY_IN); PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NFIN_OUT', NVALUE => NFIN_OUT); PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NPAY_IN_REST', NVALUE => NPAY_IN_REST); PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NCTRL_FIN', NVALUE => NCTRL_FIN); PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NFIN_REST', NVALUE => NFIN_REST); PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NCOEXEC_IN', NVALUE => NCOEXEC_IN); PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NCOEXEC_REST', NVALUE => NCOEXEC_REST); PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NCTRL_COEXEC', NVALUE => NCTRL_COEXEC); /* Добавляем строку в таблицу */ PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW); end loop; /* Освобождаем курсор */ PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR); exception when others then PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR); raise; end; /* Сериализуем описание */ COUT := PKG_P8PANELS_VISUAL.TDATA_GRID_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => NINCLUDE_DEF); end STAGE_CONTRACTS_LIST; /* Считывание записи работы проекта */ 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_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_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_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_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_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_MODIFY_PERIOD ( NJB_JOBS in number, -- Рег. номер записи балансируемой работы/этапа DDATE_FROM in date, -- Новая дата начала DDATE_TO in date, -- Новая дата окончания DBEGIN in date, -- Дата начала периода мониторинга загрузки ресурсов NRESOURCE_STATUS out number -- Состояние ресурсов (0 - без отклонений, 1 - есть отклонения) ) is RJB_J P8PNL_JB_JOBS%rowtype; -- Запись работы в буфере балансировки RJB_P P8PNL_JB_PRJCTS%rowtype; -- Запись родительского проекта в буфере балансировки begin /* Считаем работу из буфера */ RJB_J := JB_JOBS_GET(NJB_JOBS => NJB_JOBS); /* Считаем проект из буфера */ RJB_P := JB_PRJCTS_GET(NJB_PRJCTS => RJB_J.PRN); /* Изменим работу */ update P8PNL_JB_JOBS T set T.DATE_FROM = DDATE_FROM, T.DATE_TO = DDATE_TO where T.RN = RJB_J.RN; /* Выставим признак изменений в проекте */ JB_PRJCTS_SET_CHANGED(NJB_PRJCTS => RJB_P.RN, NCHANGED => 1); /* Выполним пересчёт монитора */ JB_PERIODS_RECALC(NIDENT => RJB_P.IDENT, DBEGIN => DBEGIN, NINITIAL => 0, NRESOURCE_STATUS => NRESOURCE_STATUS); 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 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 := 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 => BREAD_ONLY); /* Добавим динамические атрибуты к задачам */ 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; /* Формируем список */ 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_LIST_PLAN_FOT ( 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 NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса RPRD P8PNL_JB_PERIODS%rowtype; -- Запись детализируемого периода RO PKG_P8PANELS_VISUAL.TORDERS; -- Сортировки RDG PKG_P8PANELS_VISUAL.TDATA_GRID; -- Описание таблицы RDG_ROW PKG_P8PANELS_VISUAL.TROW; -- Строка таблицы CSQL clob; -- Буфер для запроса ICURSOR integer; -- Курсор для исполнения запроса NROW_FROM PKG_STD.TREF; -- Номер строки с NROW_TO PKG_STD.TREF; -- Номер строки по begin /* Считаем детализируемую запись периода */ RPRD := JB_PERIODS_GET(NJB_PERIODS => NJB_PERIODS); /* Читем сортировки */ RO := PKG_P8PANELS_VISUAL.TORDERS_FROM_XML(CORDERS => CORDERS); /* Преобразуем номер и размер страницы в номер строк с и по */ PKG_P8PANELS_VISUAL.UTL_ROWS_LIMITS_CALC(NPAGE_NUMBER => NPAGE_NUMBER, NPAGE_SIZE => NPAGE_SIZE, NROW_FROM => NROW_FROM, NROW_TO => NROW_TO); /* Инициализируем таблицу данных */ RDG := PKG_P8PANELS_VISUAL.TDATA_GRID_MAKE(); /* Добавляем в таблицу описание колонок */ PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NRN', SCAPTION => 'Рег. номер', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SPERSON', SCAPTION => 'Сотрудник', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, BORDER => true, BFILTER => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NLAB_PLAN_FOT', SCAPTION => 'Трудоёмкость', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BORDER => false, BFILTER => false); /* Обходим данные */ begin /* Собираем запрос */ CSQL := 'select * from (select D.*, ROWNUM NROW from (select FM.RN NRN, PERS.CODE SPERSON, SH.AVG_HOURS NLAB_PLAN_FOT from CLNPSPFM FM, CLNPERSONS PERS, CLNPSDEP PSD, PRPROF PROF, CLNPSPFMHS FMH, SLSCHEDULE SH where FM.COMPANY = :NCOMPANY and FM.PERSRN = PERS.RN and FM.DEPTRN = :NINS_DEPARTMENT and FM.PSDEPRN = PSD.RN and PSD.PRPROF = PROF.RN and PROF.RN in (select MP.PRPROF from FCMANPOWER MP where MP.RN = :NFCMANPOWER) and ((FM.BEGENG between :DDATE_FROM and :DDATE_TO) or (FM.ENDENG between :DDATE_FROM and :DDATE_TO) or ((FM.BEGENG < :DDATE_FROM) and (COALESCE(FM.ENDENG, :DDATE_TO + 1) > :DDATE_TO))) and FM.RN = FMH.PRN and ((FMH.DO_ACT_FROM between :DDATE_FROM and :DDATE_TO) or (FMH.DO_ACT_TO between :DDATE_FROM and :DDATE_TO) or ((FMH.DO_ACT_FROM < :DDATE_FROM) and (COALESCE(FMH.DO_ACT_TO, :DDATE_TO + 1) > :DDATE_TO))) and FMH.SCHEDULE = SH.RN %ORDER_BY%) D) F where F.NROW between :NROW_FROM and :NROW_TO'; /* Учтём сортировки */ PKG_P8PANELS_VISUAL.TORDERS_SET_QUERY(RDATA_GRID => RDG, RORDERS => RO, SPATTERN => '%ORDER_BY%', CSQL => CSQL); /* Разбираем его */ 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); /* Делаем выборку */ if (PKG_SQL_DML.EXECUTE(ICURSOR => ICURSOR) = 0) then null; end if; /* Обходим выбранные записи */ while (PKG_SQL_DML.FETCH_ROWS(ICURSOR => ICURSOR) > 0) loop /* Добавляем колонки с данными */ PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NRN', ICURSOR => ICURSOR, NPOSITION => 1, BCLEAR => true); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SPERSON', ICURSOR => ICURSOR, NPOSITION => 2); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NLAB_PLAN_FOT', ICURSOR => ICURSOR, NPOSITION => 3); /* Добавляем строку в таблицу */ PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW); end loop; /* Освобождаем курсор */ PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR); exception when others then PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR); raise; end; /* Сериализуем описание */ COUT := PKG_P8PANELS_VISUAL.TDATA_GRID_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => NINCLUDE_DEF); end JB_PERIODS_LIST_PLAN_FOT; /* Получение плановой трудоёмкости по ФОТ для периода балансировки (в часах) */ function JB_PERIODS_GET_PLAN_FOT ( NCOMPANY in number, -- Рег. номер организации DDATE_FROM in date, -- Начало DDATE_TO in date, -- Окончание NINS_DEPARTMENT in number, -- Рег. номер штатного подразделения NFCMANPOWER in number -- Рег. номер трудового ресурса ) return number -- Плановая трудоёмкость по ФОТ (в часах) is NRES PKG_STD.TNUMBER; -- Плановая трудоёмкость по ФОТ begin /* Обойдем подходящие исполнения и просуммируем среднемесячную численность часов */ select sum(SH.AVG_HOURS) into NRES from CLNPSPFM FM, CLNPSDEP PSD, PRPROF PROF, CLNPSPFMHS FMH, SLSCHEDULE SH where FM.COMPANY = NCOMPANY and FM.DEPTRN = NINS_DEPARTMENT and FM.PSDEPRN = PSD.RN and PSD.PRPROF = PROF.RN and PROF.RN in (select MP.PRPROF from FCMANPOWER MP where MP.RN = NFCMANPOWER) and ((FM.BEGENG between DDATE_FROM and DDATE_TO) or (FM.ENDENG between DDATE_FROM and DDATE_TO) or ((FM.BEGENG < DDATE_FROM) and (COALESCE(FM.ENDENG, DDATE_TO + 1) > DDATE_TO))) and FM.RN = FMH.PRN and ((FMH.DO_ACT_FROM between DDATE_FROM and DDATE_TO) or (FMH.DO_ACT_TO between DDATE_FROM and DDATE_TO) or ((FMH.DO_ACT_FROM < DDATE_FROM) and (COALESCE(FMH.DO_ACT_TO, DDATE_TO + 1) > DDATE_TO))) and FMH.SCHEDULE = SH.RN; /* Вернём собранный результат */ return COALESCE(NRES, 0); end JB_PERIODS_GET_PLAN_FOT; /* Получение списка для детализации трудоёмкости периода балансировки по текущему состоянию графика */ procedure JB_PERIODS_LIST_PLAN_JOBS ( 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 NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса RPRD P8PNL_JB_PERIODS%rowtype; -- Запись детализируемого периода RO PKG_P8PANELS_VISUAL.TORDERS; -- Сортировки RDG PKG_P8PANELS_VISUAL.TDATA_GRID; -- Описание таблицы RDG_ROW PKG_P8PANELS_VISUAL.TROW; -- Строка таблицы 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.TNUMBER; -- Длительнось текущей работы согласно плану-груфику NMP_LAB PKG_STD.TNUMBER; -- Трудоёмкость трудового ресурса в текущей работе согласно проекта NMP_LAB_ONE PKG_STD.TNUMBER; -- Трудоёмкость (за единицу длительности) трудового ресурса в текущей работе согласно проекта NMP_LAB_PLAN PKG_STD.TNUMBER; -- Трудоёмкость трудового ресурса в текущей работе согласно плана-графика begin /* Считаем детализируемую запись периода */ RPRD := JB_PERIODS_GET(NJB_PERIODS => NJB_PERIODS); /* Читем сортировки */ RO := PKG_P8PANELS_VISUAL.TORDERS_FROM_XML(CORDERS => CORDERS); /* Преобразуем номер и размер страницы в номер строк с и по */ PKG_P8PANELS_VISUAL.UTL_ROWS_LIMITS_CALC(NPAGE_NUMBER => NPAGE_NUMBER, NPAGE_SIZE => NPAGE_SIZE, NROW_FROM => NROW_FROM, NROW_TO => NROW_TO); /* Инициализируем таблицу данных */ RDG := PKG_P8PANELS_VISUAL.TDATA_GRID_MAKE(); /* Добавляем в таблицу описание колонок */ PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NRN', SCAPTION => 'Рег. номер', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NPROJECT', SCAPTION => 'Рег. номер проекта', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NJB_PRJCTS', SCAPTION => 'Рег. номер буфера балансировки проекта', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SPRJ', SCAPTION => 'Проект', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, BORDER => true, BFILTER => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SSTG_JOB', SCAPTION => 'Этап-работа', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, BORDER => true, BFILTER => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SJOB_NAME', SCAPTION => 'Наим. работы', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, BORDER => true, BFILTER => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NJOB_STATE', SCAPTION => 'Сост. работы', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BORDER => true, BFILTER => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'DJOB_BEG', SCAPTION => 'Начало работы', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_DATE, BORDER => true, BFILTER => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'DJOB_END', SCAPTION => 'Окончание работы', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_DATE, BORDER => true, BFILTER => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NJOB_DUR', SCAPTION => 'Длительн. работы', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BORDER => false, BFILTER => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NMP_LAB', SCAPTION => 'Труд.', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BORDER => false, BFILTER => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NMP_LAB_ONE', SCAPTION => 'Труд. (в ед. длит.)', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BORDER => false, BFILTER => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NMP_LAB_PLAN', SCAPTION => 'Труд. (план, график)', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BORDER => false, BFILTER => false); /* Обходим данные */ begin /* Собираем запрос */ CSQL := 'select * from (select D.*, ROWNUM NROW from (select JB.RN NRN, P.RN NPROJECT, JBP.RN NJB_PRJCTS, P.CODE || ''-'' || P.NAME_USL SPRJ, trim(PS.NUMB) || ''-'' || trim(PJ.NUMB) SSTG_JOB, PJ.NAME SJOB_NAME, PJ.STATE NJOB_STATE, JB.DATE_FROM DJOB_BEG, JB.DATE_TO DJOB_END, PJMP.LABOUR_P NLABOUR_P from P8PNL_JB_JOBS JB, P8PNL_JB_PRJCTS JBP, PROJECTJOB PJ, PROJECTJOBMANPOW PJMP, PROJECT P, PROJECTSTAGE PS where JB.IDENT = :NIDENT and JB.STAGE = 0 and JB.PRN = JBP.RN and JB.SOURCE = PJ.RN and PJ.COMPANY = :NCOMPANY and PJ.PRN = P.RN and PJ.PROJECTSTAGE = PS.RN(+) and PJ.RN = PJMP.PRN and PJMP.FCMANPOWER = :NFCMANPOWER and PJMP.SUBDIV = :NINS_DEPARTMENT and ((JB.DATE_FROM between :DDATE_FROM and :DDATE_TO) or (JB.DATE_TO between :DDATE_FROM and :DDATE_TO) or ((JB.DATE_FROM < :DDATE_FROM) and (JB.DATE_TO > :DDATE_TO))) %ORDER_BY%) D) F where F.NROW between :NROW_FROM and :NROW_TO'; /* Учтём сортировки */ PKG_P8PANELS_VISUAL.TORDERS_SET_QUERY(RDATA_GRID => RDG, RORDERS => RO, SPATTERN => '%ORDER_BY%', CSQL => CSQL); /* Разбираем его */ 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); /* Делаем выборку */ 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); P_PROJECTJOB_GET_DURATION(NCOMPANY => NCOMPANY, DBEG_DATE => DJOB_BEG, DEND_DATE => DJOB_END, NDURATION_MEAS => NJB_DURATION_MEAS, NDURATION => NJOB_DUR); 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 := NMP_LAB / (DJOB_END - DJOB_BEG); else NMP_LAB_ONE := NMP_LAB; end if; NMP_LAB_PLAN := (DEND - DBEG) * NMP_LAB_ONE; /* Добавляем колонки с данными */ PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NRN', ICURSOR => ICURSOR, NPOSITION => 1, BCLEAR => true); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NPROJECT', ICURSOR => ICURSOR, NPOSITION => 2); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NJB_PRJCTS', ICURSOR => ICURSOR, NPOSITION => 3); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SPRJ', ICURSOR => ICURSOR, NPOSITION => 4); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SSTG_JOB', ICURSOR => ICURSOR, NPOSITION => 5); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SJOB_NAME', ICURSOR => ICURSOR, NPOSITION => 6); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NJOB_STATE', ICURSOR => ICURSOR, NPOSITION => 7); PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'DJOB_BEG', DVALUE => DJOB_BEG); PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'DJOB_END', DVALUE => DJOB_END); PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NJOB_DUR', NVALUE => NJOB_DUR); PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NMP_LAB', NVALUE => NMP_LAB); PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NMP_LAB_ONE', NVALUE => NMP_LAB_ONE); PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NMP_LAB_PLAN', NVALUE => NMP_LAB_PLAN); /* Добавляем строку в таблицу */ PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW); end loop; /* Освобождаем курсор */ PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR); exception when others then PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR); raise; end; /* Сериализуем описание */ COUT := PKG_P8PANELS_VISUAL.TDATA_GRID_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => NINCLUDE_DEF); end JB_PERIODS_LIST_PLAN_JOBS; /* Получение плановой трудоёскости по текущему состоянию графиков в буфере балансировки для периода балансировки */ function JB_PERIODS_GET_PLAN_JOBS ( NIDENT in number, -- Идентификатор процесса DDATE_FROM in date, -- Начало DDATE_TO in date, -- Окончание NINS_DEPARTMENT in number, -- Рег. номер штатного подразделения NFCMANPOWER in number -- Рег. номер трудового ресурса ) return number -- Плановая трудоёмкость по текущему состоянию графиков в буфере балансировки is NRES PKG_STD.TNUMBER; -- Буфер для результата NPLAN_JOB PKG_STD.TNUMBER; -- Плановая трудоёмкость текущей работы согласно графика DBEG PKG_STD.TLDATE; -- Дата начала для расчёта трудоёмкости текущей работы DEND PKG_STD.TLDATE; -- Дата окончания для расчёта трудоёмкости текущей работы begin /* Обходим все работы в буфере подходящие по условиям */ for C in (select JB.*, PJMP.LABOUR_P from P8PNL_JB_JOBS JB, PROJECTJOB PJ, PROJECTJOBMANPOW PJMP where JB.IDENT = NIDENT and JB.STAGE = 0 and JB.SOURCE = PJ.RN and PJ.RN = PJMP.PRN and PJMP.FCMANPOWER = NFCMANPOWER and PJMP.SUBDIV = NINS_DEPARTMENT and ((JB.DATE_FROM between DDATE_FROM and DDATE_TO) or (JB.DATE_TO between DDATE_FROM and DDATE_TO) or ((JB.DATE_FROM < DDATE_FROM) and (JB.DATE_TO > DDATE_TO)))) loop /* Вычислим трудоёмкость по графику для попавшейся работы */ DBEG := DDATE_FROM; if (C.DATE_FROM > DDATE_FROM) then DBEG := C.DATE_FROM; end if; DEND := DDATE_TO; if (C.DATE_TO < DDATE_TO) then DEND := C.DATE_TO; end if; if (C.LABOUR_P <> 0) then if (C.DATE_TO - C.DATE_FROM <> 0) then NPLAN_JOB := (DEND - DBEG) * (C.LABOUR_P / (C.DATE_TO - C.DATE_FROM)); else NPLAN_JOB := (DEND - DBEG) * C.LABOUR_P; end if; else NPLAN_JOB := 0; end if; /* Накопим сумму в буфере результата */ NRES := COALESCE(NRES, 0) + NPLAN_JOB; end loop; /* Вернём собранный результат */ return COALESCE(NRES, 0); end JB_PERIODS_GET_PLAN_JOBS; /* Базовое добавление периода балансировки работ */ 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, -- Идентификатор процесса DBEGIN in date, -- Дата начала периода мониторинга загрузки ресурсов NINITIAL in number, -- Признак первоначального рассчёта (0 - пересчёт, 1 - первоначальный рассчёт) NRESOURCE_STATUS out number -- Состояние ресурсов (0 - без отклонений, 1 - есть отклонения) ) is NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса 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.TNUMBER; -- Плановая трудоёмкость по ФОТ для текущего месяца периода балансировки NLAB_PLAN_JOBS PKG_STD.TNUMBER; -- Плановая трудоёмкость по плану-графику в буфере для текущего месяца периода балансировки begin /* Подчистка при перерасчёте */ if (NINITIAL = 0) then JB_PERIODS_CLEAN(NIDENT => NIDENT); end if; /* Скажем, что нет отклонений */ NRESOURCE_STATUS := 0; /* Определим период балансировки */ DJB_BEG := DBEGIN; 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 group by JMP.FCMANPOWER, JMP.SUBDIV) loop /* Рассчитаем трудоёмкость по ФОТ (в часах) */ NLAB_PLAN_FOT := JB_PERIODS_GET_PLAN_FOT(NCOMPANY => NCOMPANY, DDATE_FROM => DBEG, DDATE_TO => DEND, NINS_DEPARTMENT => D.SUBDIV, NFCMANPOWER => D.FCMANPOWER); /* Рассчитаем трудоёмкость по работам графика */ NLAB_PLAN_JOBS := JB_PERIODS_GET_PLAN_JOBS(NIDENT => NIDENT, DDATE_FROM => DBEG, DDATE_TO => DEND, NINS_DEPARTMENT => D.SUBDIV, NFCMANPOWER => D.FCMANPOWER); /* Добавим запись периода балансировки */ JB_PERIODS_BASE_INSERT(NIDENT => NIDENT, DDATE_FROM => DBEG, DDATE_TO => DEND, NINS_DEPARTMENT => D.SUBDIV, NFCMANPOWER => D.FCMANPOWER, NLAB_PLAN_FOT => NLAB_PLAN_FOT, NLAB_FACT_RPT => 0, NLAB_PLAN_JOBS => NLAB_PLAN_JOBS, NJB_PERIODS => NJB_PERIODS); /* Если плановая трудоёмкость по работам графика превысила ФОТ - значит с ресурсами всё плохо */ 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 RO PKG_P8PANELS_VISUAL.TORDERS; -- Сортировки RDG PKG_P8PANELS_VISUAL.TDATA_GRID; -- Описание таблицы RDG_ROW PKG_P8PANELS_VISUAL.TROW; -- Строка таблицы CSQL clob; -- Буфер для запроса ICURSOR integer; -- Курсор для исполнения запроса NROW_FROM PKG_STD.TREF; -- Номер строки с NROW_TO PKG_STD.TREF; -- Номер строки по begin /* Читем сортировки */ RO := PKG_P8PANELS_VISUAL.TORDERS_FROM_XML(CORDERS => CORDERS); /* Преобразуем номер и размер страницы в номер строк с и по */ PKG_P8PANELS_VISUAL.UTL_ROWS_LIMITS_CALC(NPAGE_NUMBER => NPAGE_NUMBER, NPAGE_SIZE => NPAGE_SIZE, NROW_FROM => NROW_FROM, NROW_TO => NROW_TO); /* Инициализируем таблицу данных */ RDG := PKG_P8PANELS_VISUAL.TDATA_GRID_MAKE(); /* Добавляем в таблицу описание колонок */ PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NRN', SCAPTION => 'Рег. номер', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BVISIBLE => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SPERIOD', SCAPTION => 'Период', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, BORDER => true, BFILTER => false); PKG_P8PANELS_VISUAL.TDATA_GRID_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.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'SFCMANPOWER', SCAPTION => 'Ресурс', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, BORDER => true, BFILTER => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NLAB_PLAN_FOT', SCAPTION => 'Труд. (план, ФОТ)', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BORDER => true, BFILTER => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NLAB_FACT_RPT', SCAPTION => 'Труд. (факт, отчёт)', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BVISIBLE => false, BORDER => true, BFILTER => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NLAB_DIFF_RPT_FOT', SCAPTION => 'Отклон. (факт-план)', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BVISIBLE => false, BORDER => true, BFILTER => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NLAB_PLAN_JOBS', SCAPTION => 'Труд. (план, график)', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BORDER => true, BFILTER => false); PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG, SNAME => 'NLAB_DIFF_JOBS_FOT', SCAPTION => 'Отклон. (график-план)', SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, BORDER => true, BFILTER => false); /* Обходим данные */ begin /* Собираем запрос */ CSQL := 'select * from (select D.*, ROWNUM NROW from (select P.RN NRN, TO_CHAR(P.DATE_FROM, ''YYYY.MM'') SPERIOD, INSD.CODE SINS_DEPARTMENT, MP.CODE SFCMANPOWER, P.LAB_PLAN_FOT NLAB_PLAN_FOT, P.LAB_FACT_RPT NLAB_FACT_RPT, P.LAB_FACT_RPT - P.LAB_PLAN_FOT NLAB_DIFF_RPT_FOT, P.LAB_PLAN_JOBS NLAB_PLAN_JOBS, P.LAB_PLAN_JOBS - P.LAB_PLAN_FOT NLAB_DIFF_JOBS_FOT from P8PNL_JB_PERIODS P, INS_DEPARTMENT INSD, FCMANPOWER MP where P.IDENT = :NIDENT and P.INS_DEPARTMENT = INSD.RN and P.FCMANPOWER = MP.RN %ORDER_BY%) D) F where F.NROW between :NROW_FROM and :NROW_TO'; /* Учтём сортировки */ PKG_P8PANELS_VISUAL.TORDERS_SET_QUERY(RDATA_GRID => RDG, RORDERS => RO, SPATTERN => '%ORDER_BY%', CSQL => CSQL); /* Разбираем его */ 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); /* Делаем выборку */ if (PKG_SQL_DML.EXECUTE(ICURSOR => ICURSOR) = 0) then null; end if; /* Обходим выбранные записи */ while (PKG_SQL_DML.FETCH_ROWS(ICURSOR => ICURSOR) > 0) loop /* Добавляем колонки с данными */ PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NRN', ICURSOR => ICURSOR, NPOSITION => 1, BCLEAR => true); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SPERIOD', ICURSOR => ICURSOR, NPOSITION => 2); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SINS_DEPARTMENT', ICURSOR => ICURSOR, NPOSITION => 3); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SFCMANPOWER', ICURSOR => ICURSOR, NPOSITION => 4); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NLAB_PLAN_FOT', ICURSOR => ICURSOR, NPOSITION => 5); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NLAB_FACT_RPT', ICURSOR => ICURSOR, NPOSITION => 6); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NLAB_DIFF_RPT_FOT', ICURSOR => ICURSOR, NPOSITION => 7); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NLAB_PLAN_JOBS', ICURSOR => ICURSOR, NPOSITION => 8); PKG_P8PANELS_VISUAL.TROW_ADD_CUR_COLN(RROW => RDG_ROW, SNAME => 'NLAB_DIFF_JOBS_FOT', ICURSOR => ICURSOR, NPOSITION => 9); /* Добавляем строку в таблицу */ PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW); end loop; /* Освобождаем курсор */ PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR); exception when others then PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR); raise; end; /* Сериализуем описание */ COUT := PKG_P8PANELS_VISUAL.TDATA_GRID_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => NINCLUDE_DEF); end JB_PERIODS_LIST; /* Очистка данных балансировки */ procedure JB_CLEAN ( NIDENT in number -- Идентификатор буфера сформированных данных ) is begin /* Удаляем список предшествующих работ */ 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_INIT ( DBEGIN in out date, -- Дата начала периода мониторинга загрузки ресурсов DFACT in out date, -- Факт по состоянию на NDURATION_MEAS in out number, -- Единица измерения длительности (0 - день, 1 - неделя, 2 - декада, 3 - месяц, 4 - квартал, 5 - год) SLAB_MEAS in 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(); -- Пользователь сеанса NUTILIZER_AGENT PKG_STD.TREF; -- Рег. номер контрагента текущего пользователя 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; -- Признак возможности редактирования работы NLAB_MEAS PKG_STD.TREF; -- Рег. номер выбранной для рассчётов единицы измерения трудоёмкости begin /* Обработаем дату начала периода мониторинга загрузки ресурсов */ if (DBEGIN is null) then DBEGIN := TRUNC(sysdate, 'yyyy'); else DBEGIN := TRUNC(DBEGIN, 'yyyy'); end if; /* Обработаем единицу измерения длительности (пока - она всегда должна быть "день", по умолчанию) */ NDURATION_MEAS := NJB_DURATION_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; /* Найдем контрагента, соответствующего текущему пользователю */ FIND_AGNLIST_AUTHID(NFLAG_OPTION => 1, NCOMPANY => NCOMPANY, SPERS_AUTHID => SUTILIZER, NAGENT => NUTILIZER_AGENT); /* Обходим проекты */ 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, COALESCE((select 1 from AGNLIST AG where AG.RN = P.RESPONSIBLE and AG.RN = NUTILIZER_AGENT), 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 /* Помещаем проект в список балансируемых */ 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 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 not in (0, 1))) 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) 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, DBEGIN => DBEGIN, NINITIAL => 1, NRESOURCE_STATUS => NRESOURCE_STATUS); end JB_INIT; end PKG_P8PANELS_PROJECTS; /