diff --git a/app/panels/mech_rec_cost_prod_plans/mech_rec_cost_prod_plans.js b/app/panels/mech_rec_cost_prod_plans/mech_rec_cost_prod_plans.js
index 13c6940..c65679a 100644
--- a/app/panels/mech_rec_cost_prod_plans/mech_rec_cost_prod_plans.js
+++ b/app/panels/mech_rec_cost_prod_plans/mech_rec_cost_prod_plans.js
@@ -36,7 +36,8 @@ import {
Card,
CardHeader,
CardContent,
- CardActions
+ CardActions,
+ Tooltip
} from "@mui/material"; //Интерфейсные элементы
import { BackEndСtx } from "../../context/backend"; //Контекст взаимодействия с сервером
import { MessagingСtx } from "../../context/messaging"; //Контекст сообщений
@@ -55,19 +56,34 @@ import { IncomFromDepsDataGrid } from "./datagrids/incomefromdeps"; //Табли
//---------
//Склонения для документов
-const DECLINATIONS = ["план", "плана", "планов"];
+const PLANS_DECLINATIONS = ["план", "плана", "планов"];
+const SPEC_DECLINATIONS = ["элемент", "элемента", "элементов"];
//Поля сортировки
const SORT_REP_DATE = "DREP_DATE";
const SORT_REP_DATE_TO = "DREP_DATE_TO";
+//Максимальное количество элементов
+const MAX_TASKS = 10000;
+
//Стили
const STYLES = {
PLANS_FINDER: { marginTop: "10px", marginLeft: "10px", width: "93%" },
PLANS_CHECKBOX_HAVEDOCS: { alignContent: "space-around" },
+ PLANS_LIST_CONTAINER: { height: "100%", display: "flex", flexDirection: "column", justifyContent: "space-between" },
PLANS_LIST_ITEM_ZERODOCS: { backgroundColor: "#ebecec" },
PLANS_LIST_ITEM_PRIMARY: { wordWrap: "break-word" },
PLANS_LIST_ITEM_SECONDARY: { wordWrap: "break-word", fontSize: "0.6rem", textTransform: "uppercase" },
+ PLANS_LIST_ITEM_PLAN: {
+ backgroundColor: "#c7e7f1",
+ "&:hover": { backgroundColor: `#c7e7f1`, filter: "brightness(0.92) !important" }
+ },
+ PLANS_LIST_ITEM_PLAN_FIELD: {
+ marginLeft: "15px"
+ },
+ PLANS_LIST_FILTER_CONTAINER: { height: "calc(100% - 55px)", overflowY: "auto" },
+ PLANS_LIST_BUTTONS_CONTAINER: { display: "flex", justifyContent: "space-around", paddingBottom: "10px", height: "45px" },
+ PLANS_LIST_BUTTON: { minWidth: "125px", height: "35px" },
PLANS_BUTTON: { position: "absolute", top: `calc(${APP_BAR_HEIGHT} + 16px)`, left: "16px" },
PLANS_DRAWER: {
width: "350px",
@@ -121,7 +137,9 @@ const parseProdPlanSpXML = async xmlDoc => {
};
//Форматирование для отображения количества документов
-const formatCountDocs = nCountDocs => {
+const formatCountDocs = (nCountDocs, nType = 0) => {
+ //Склонение документов
+ let DECLINATIONS = nType === 0 ? PLANS_DECLINATIONS : SPEC_DECLINATIONS;
//Получаем последнюю цифру в значении
let num = (nCountDocs % 100) % 10;
//Документов
@@ -134,55 +152,146 @@ const formatCountDocs = nCountDocs => {
return `${nCountDocs} ${DECLINATIONS[2]}`;
};
+//Изменение информации об отмеченных планах
+const updateCtlgPlanInfo = (selectedPlans, plan) => {
+ //Результат изменений
+ let res = { selectedPlans: [...selectedPlans] || [], selectedPlansElements: plan.NCOUNT_DOCS };
+ //Определяем наличие в отмеченных планах
+ let selectedIndex = res.selectedPlans.indexOf(plan.NRN);
+ //Если уже есть в отмеченных - удаляем, нет - добавляем
+ if (selectedIndex > -1) {
+ //Удаляем план из выбранных
+ res.selectedPlans.splice(selectedIndex, 1);
+ //Переворачиваем сумму документов
+ res.selectedPlansElements = res.selectedPlansElements * -1;
+ } else {
+ //Добавляем план в выбранные
+ res.selectedPlans.push(plan.NRN);
+ }
+ //Возвращаем результат
+ return res;
+};
+
//Список каталогов планов
-const PlanCtlgsList = ({ planCtlgs = [], selectedPlanCtlg, filter, setFilter, onClick } = {}) => {
+const PlanCtlgsList = ({
+ planCtlgs = [],
+ selectedPlans = [],
+ selectedPlanCtlg,
+ selectedPlansElements,
+ filter,
+ setFilter,
+ onCtlgClick,
+ onCtlgPlanClick,
+ onCtlgPlansOk,
+ onCtlgPlansCancel
+} = {}) => {
//Генерация содержимого
return (
-
- {
- setFilter(pv => ({ ...pv, ctlgName: event.target.value }));
- }}
- >
-
- setFilter(pv => ({ ...pv, haveDocs: event.target.checked }))} />}
- label="Только с планами"
- labelPlacement="end"
- />
-
-
- {planCtlgs.map(p => (
- (onClick ? onClick(p) : null)}
- >
- {p.SNAME}}
- secondary={{formatCountDocs(p.NCOUNT_DOCS)}}
- />
-
- ))}
-
-
+
+
+ {
+ setFilter(pv => ({ ...pv, ctlgName: event.target.value }));
+ }}
+ >
+
+ setFilter(pv => ({ ...pv, haveDocs: event.target.checked }))} />
+ }
+ label="Только с планами"
+ labelPlacement="end"
+ />
+
+
+ {planCtlgs.map(ctlg => (
+
+ (onCtlgClick ? onCtlgClick(ctlg) : null)}
+ disabled={ctlg.NCOUNT_DOCS == 0}
+ >
+ {ctlg.SNAME}}
+ secondary={{formatCountDocs(ctlg.NCOUNT_DOCS, 0)}}
+ />
+
+ {ctlg.NRN === selectedPlanCtlg && ctlg.XCRN_PLANS.length > 1
+ ? ctlg.XCRN_PLANS.map(plan => (
+ (onCtlgPlanClick ? onCtlgPlanClick(plan) : null)}
+ >
+ {plan.SNAME}}
+ secondary={
+
+ {formatCountDocs(plan.NCOUNT_DOCS, 1)}
+
+ }
+ />
+ {plan.NCOUNT_DOCS !== 0 ? : null}
+
+ ))
+ : null}
+
+ ))}
+
+
+
+ MAX_TASKS
+ ? `Выбранные планы превышают максимум элементов (выбрано: ${selectedPlansElements}, максимум: ${MAX_TASKS})`
+ : null
+ }
+ >
+
+
+
+
+
+
+
);
};
//Контроль свойств - Список каталогов планов
PlanCtlgsList.propTypes = {
planCtlgs: PropTypes.array,
+ selectedPlans: PropTypes.array,
selectedPlanCtlg: PropTypes.number,
- onClick: PropTypes.func,
+ selectedPlansElements: PropTypes.number,
+ onCtlgClick: PropTypes.func,
+ onCtlgPlanClick: PropTypes.func,
filter: PropTypes.object,
- setFilter: PropTypes.func
+ setFilter: PropTypes.func,
+ onCtlgPlansOk: PropTypes.func,
+ onCtlgPlansCancel: PropTypes.func
};
//Генерация диалога задачи
@@ -251,6 +360,8 @@ const MechRecCostProdPlans = () => {
showPlanList: false,
planCtlgs: [],
planCtlgsLoaded: false,
+ selectedPlans: [],
+ selectedPlansElements: 0,
selectedPlanCtlgSpecsLoaded: false,
selectedPlanCtlg: null,
selectedPlanCtlgMaxLevel: null,
@@ -258,6 +369,9 @@ const MechRecCostProdPlans = () => {
selectedPlanCtlgOutOfLimit: 0,
selectedPlanCtlgSort: null,
selectedPlanCtlgMenuItems: null,
+ loadedCtlg: null,
+ loadedPlans: [],
+ loadedElements: 0,
gantt: {},
selectedTaskDetail: null,
selectedTaskDetailType: null,
@@ -273,7 +387,7 @@ const MechRecCostProdPlans = () => {
const { InlineMsgInfo } = useContext(MessagingСtx);
//Подключение к контексту взаимодействия с сервером
- const { executeStored } = useContext(BackEndСtx);
+ const { executeStored, SERV_DATA_TYPE_CLOB } = useContext(BackEndСtx);
//Подключение к контексту навигации
const { getNavigationSearch } = useContext(NavigationCtx);
@@ -288,54 +402,28 @@ const MechRecCostProdPlans = () => {
stored: "PKG_P8PANELS_MECHREC.FCPRODPLAN_PP_CTLG_INIT",
args: {},
respArg: "COUT",
- isArray: name => name === "XFCPRODPLAN_CRNS"
+ isArray: name => ["XFCPRODPLAN_CRNS", "XCRN_PLANS"].includes(name)
});
setState(pv => ({ ...pv, init: true, planCtlgs: [...(data?.XFCPRODPLAN_CRNS || [])], planCtlgsLoaded: true }));
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [state.init, executeStored]);
- //Выбор каталога планов
- const selectPlan = project => {
- setState(pv => ({
- ...pv,
- selectedPlanCtlg: project,
- selectedPlanCtlgSpecsLoaded: false,
- selectedPlanCtlgMaxLevel: null,
- selectedPlanCtlgLevel: null,
- selectedPlanCtlgOutOfLimit: 0,
- selectedPlanCtlgSort: null,
- selectedPlanCtlgMenuItems: null,
- gantt: {},
- showPlanList: false,
- selectedTaskDetail: null,
- selectedTaskDetailType: null
- }));
- };
-
- //Сброс выбора каталога планов
- const unselectPlan = () =>
- setState(pv => ({
- ...pv,
- selectedPlanCtlgSpecsLoaded: false,
- selectedPlanCtlg: null,
- selectedPlanCtlgMaxLevel: null,
- selectedPlanCtlgLevel: null,
- selectedPlanCtlgOutOfLimit: 0,
- selectedPlanCtlgSort: null,
- selectedPlanCtlgMenuItems: null,
- gantt: {},
- showPlanList: false,
- selectedTaskDetail: null,
- selectedTaskDetailType: null
- }));
-
//Загрузка списка спецификаций каталога планов
const loadPlanCtglSpecs = useCallback(
async (level = null, sort = null) => {
const data = await executeStored({
stored: "PKG_P8PANELS_MECHREC.FCPRODPLANSP_GET",
- args: { NCRN: state.selectedPlanCtlg, NLEVEL: level, SSORT_FIELD: sort, NFCPRODPLANSP: state.planSpec }
+ args: {
+ NCRN: state.selectedPlanCtlg,
+ CFCPRODPLANS: {
+ VALUE: state.selectedPlans.length > 0 ? state.selectedPlans.join(";") : null,
+ SDATA_TYPE: SERV_DATA_TYPE_CLOB
+ },
+ NLEVEL: level,
+ SSORT_FIELD: sort,
+ NFCPRODPLANSP: state.planSpec
+ }
});
let doc = await parseProdPlanSpXML(data.COUT);
setState(pv => ({
@@ -344,21 +432,71 @@ const MechRecCostProdPlans = () => {
selectedPlanCtlgLevel: level || level === 0 ? level : data.NMAX_LEVEL,
selectedPlanCtlgOutOfLimit: data.NOUT_OF_LIMIT,
selectedPlanCtlgSort: sort,
- selectedPlanCtlgMenuItems: state.selectedPlanCtlgMenuItems
- ? state.selectedPlanCtlgMenuItems
- : [...Array(data.NMAX_LEVEL).keys()].map(el => el + 1),
+ selectedPlanCtlgMenuItems: [...Array(data.NMAX_LEVEL).keys()].map(el => el + 1),
selectedPlanCtlgSpecsLoaded: true,
- gantt: { ...doc, tasks: [...(doc?.tasks || [])] }
+ gantt: { ...doc, tasks: [...(doc?.tasks || [])] },
+ loadedCtlg: state.selectedPlanCtlg,
+ loadedPlans: [...state.selectedPlans],
+ loadedElements: state.selectedPlansElements,
+ showPlanList: false
}));
},
// eslint-disable-next-line react-hooks/exhaustive-deps
- [executeStored, state.ident, state.selectedPlanCtlg, state.planSpec]
+ [executeStored, state.selectedPlanCtlg, state.selectedPlans, state.planSpec]
);
//Обработка нажатия на элемент в списке каталогов планов
- const handleProjectClick = project => {
- if (state.selectedPlanCtlg != project.NRN) selectPlan(project.NRN);
- else unselectPlan();
+ const handleCtlgClick = project => {
+ //Если этот каталог не был выбран
+ if (state.selectedPlanCtlg != project.NRN) {
+ //Если выбран уже загруженный - укажем информацию о том, как он загружен
+ if (project.NRN === state.loadedCtlg) {
+ setState(pv => ({
+ ...pv,
+ selectedPlanCtlg: project.NRN,
+ selectedPlans: [...pv.loadedPlans],
+ selectedPlansElements: pv.loadedElements
+ }));
+ } else {
+ setState(pv => ({
+ ...pv,
+ selectedPlanCtlg: project.NRN,
+ selectedPlans: project.XCRN_PLANS.length === 1 ? [project.XCRN_PLANS[0].NRN] : [],
+ selectedPlansElements: 0
+ }));
+ }
+ } else {
+ setState(pv => ({ ...pv, selectedPlanCtlg: null, selectedPlans: [], selectedPlansElements: 0 }));
+ }
+ };
+
+ //Обработка нажатия на элемент в списке планов каталога
+ const handleCtlgPlanClick = plan => {
+ //Считываем обновленную информацию об отмеченных планах
+ let newPlansInfo = updateCtlgPlanInfo(state.selectedPlans, plan);
+ //Обновляем список отмеченных планов
+ setState(pv => ({
+ ...pv,
+ selectedPlans: [...newPlansInfo.selectedPlans],
+ selectedPlansElements: pv.selectedPlansElements + newPlansInfo.selectedPlansElements
+ }));
+ };
+
+ //Обработка нажатия "ОК" при отборе планов
+ const handleSelectedPlansOk = () => {
+ //Загружаем диаграмму
+ loadPlanCtglSpecs(null, SORT_REP_DATE_TO);
+ };
+
+ //Обработка нажатия "Отмена" при отборе планов
+ const handleSelectedPlansCancel = () => {
+ setState(pv => ({
+ ...pv,
+ selectedPlanCtlg: pv.loadedCtlg,
+ selectedPlans: [...pv.loadedPlans] || [],
+ selectedPlansElements: pv.loadedElements,
+ showPlanList: false
+ }));
};
//При подключении компонента к странице
@@ -371,8 +509,8 @@ const MechRecCostProdPlans = () => {
//При смене выбранного каталога плана или при явном указании позиции спецификации плана
useEffect(() => {
- if (state.selectedPlanCtlg || state.planSpec) loadPlanCtglSpecs(null, SORT_REP_DATE_TO);
- }, [state.selectedPlanCtlg, state.planSpec, loadPlanCtglSpecs]);
+ if (state.planSpec) loadPlanCtglSpecs(null, SORT_REP_DATE_TO);
+ }, [state.planSpec, loadPlanCtglSpecs]);
//Выбор уровня
const handleChangeSelectLevel = selectedLevel => {
@@ -415,18 +553,18 @@ const MechRecCostProdPlans = () => {
setState(pv => ({ ...pv, showPlanList: !pv.showPlanList }))}>
Каталоги планов
- setState(pv => ({ ...pv, showPlanList: false }))}
- sx={STYLES.PLANS_DRAWER}
- >
+
>
@@ -508,14 +646,14 @@ const MechRecCostProdPlans = () => {
/>
)
- ) : !state.selectedPlanCtlg ? (
+ ) : !state.loadedCtlg ? (
diff --git a/db/PKG_P8PANELS_MECHREC.pck b/db/PKG_P8PANELS_MECHREC.pck
index facfc0c..e352e59 100644
--- a/db/PKG_P8PANELS_MECHREC.pck
+++ b/db/PKG_P8PANELS_MECHREC.pck
@@ -81,6 +81,7 @@ create or replace package PKG_P8PANELS_MECHREC as
procedure FCPRODPLANSP_GET
(
NCRN in number, -- Рег. номер каталога
+ CFCPRODPLANS in clob, -- Список отмеченных планов (разделитель - ";")
NFCPRODPLANSP in number, -- Рег. номер позиции спецификации
NLEVEL in number := null, -- Уровень отбора
SSORT_FIELD in varchar2 := 'DREP_DATE_TO', -- Поле сортировки
@@ -513,6 +514,28 @@ create or replace package body PKG_P8PANELS_MECHREC as
end;
end UTL_FCROUTLST_GET;
+ /* Иницализация выбранных планов */
+ procedure UTL_FCPRODPLAN_IDENT_INIT
+ (
+ CFCPRODPLANS in clob, -- Список отмеченных планов (разделитель - ";")
+ NIDENT out number -- Идентификатор отмеченных записей
+ )
+ is
+ NFCPRODPLAN PKG_STD.TREF; -- Рег. номер плана
+ NTMP PKG_STD.TREF; -- Буфер
+ begin
+ /* Генерируем идентификатор */
+ NIDENT := GEN_IDENT();
+ /* Обходим исполнителей */
+ for I in 1 .. STRCNT(source => CFCPRODPLANS, DELIMETER => ';')
+ loop
+ /* Считываем рег. номер плана */
+ NFCPRODPLAN := TO_NUMBER(STRTOK(source => CFCPRODPLANS, DELIMETER => ';', ITEM => I));
+ /* Добавляем в селектлист */
+ P_SELECTLIST_INSERT(NIDENT => NIDENT, NDOCUMENT => NFCPRODPLAN, SUNITCODE => 'CostProductPlans', NRN => NTMP);
+ end loop;
+ end UTL_FCPRODPLAN_IDENT_INIT;
+
/* Считывания рег. номера подразделения пользователя */
function UTL_SUBDIV_RN_GET
(
@@ -2259,6 +2282,7 @@ create or replace package body PKG_P8PANELS_MECHREC as
procedure FCPRODPLANSP_GET
(
NCRN in number, -- Рег. номер каталога
+ CFCPRODPLANS in clob, -- Список отмеченных планов (разделитель - ";")
NFCPRODPLANSP in number, -- Рег. номер позиции спецификации
NLEVEL in number := null, -- Уровень отбора
SSORT_FIELD in varchar2 := 'DREP_DATE_TO', -- Поле сортировки
@@ -2284,6 +2308,7 @@ create or replace package body PKG_P8PANELS_MECHREC as
NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса
NTASK_CLASS PKG_STD.TNUMBER; -- Класс задачи (см. константы NCLASS_*)
NLEVEL_FILTER PKG_STD.TNUMBER; -- Уровень для фильтра
+ NPLANS_IDENT PKG_STD.TREF; -- Идентификатор отмеченных планов
/* Объединение значений в строковое представление */
function MAKE_INFO
@@ -2308,6 +2333,7 @@ create or replace package body PKG_P8PANELS_MECHREC as
procedure PRODPLAN_MAX_LEVEL_GET
(
NCRN in number, -- Рег. номер каталога планов
+ NPLANS_IDENT in number, -- Идентификатор отмеченных планов
NFCPRODPLANSP in number, -- Рег. номер позиции спецификации
NMAX_LEVEL out number, -- Максимальный уровень иерархии
NOUT_OF_LIMIT out number -- Признак превышения лимита (0 - нет, 1 - да)
@@ -2328,6 +2354,12 @@ create or replace package body PKG_P8PANELS_MECHREC as
FCPRODPLANSP T,
FINSTATE FS
where ((NCRN is null) or ((NCRN is not null) and (P.CRN = NCRN)))
+ and ((NPLANS_IDENT is null) or
+ ((NPLANS_IDENT is not null) and
+ (P.RN in (select SL.DOCUMENT
+ from SELECTLIST SL
+ where SL.IDENT = NPLANS_IDENT
+ and SL.UNITCODE = 'CostProductPlans'))))
and ((NFCPRODPLANSP is null) or
((NFCPRODPLANSP is not null) and
(P.RN = (select PRN from FCPRODPLANSP where RN = NFCPRODPLANSP))))
@@ -2711,12 +2743,18 @@ create or replace package body PKG_P8PANELS_MECHREC as
begin
/* Определяем заголовок плана */
if (NCRN is not null) then
+ /* Считываем каталог */
FIND_ACATALOG_RN(NFLAG_SMART => 0,
NCOMPANY => NCOMPANY,
NVERSION => null,
SUNITCODE => 'CostProductPlans',
NRN => NCRN,
SNAME => SPLAN_TITLE);
+ /* Если есть выбранные планы */
+ if (CFCPRODPLANS is not null) then
+ /* Инициализируем отмеченные планы в селектлисте */
+ UTL_FCPRODPLAN_IDENT_INIT(CFCPRODPLANS => CFCPRODPLANS, NIDENT => NPLANS_IDENT);
+ end if;
else
if (NFCPRODPLANSP is not null) then
begin
@@ -2750,9 +2788,10 @@ create or replace package body PKG_P8PANELS_MECHREC as
/* Инициализируем описания цветов */
TASK_COLORS_INIT(RG => RG);
/* Определяем максимальный уровень иерархии */
- PRODPLAN_MAX_LEVEL_GET(NCRN => NCRN,
- NFCPRODPLANSP => NFCPRODPLANSP,
- NMAX_LEVEL => NMAX_LEVEL,
+ PRODPLAN_MAX_LEVEL_GET(NCRN => NCRN,
+ NPLANS_IDENT => NPLANS_IDENT,
+ NFCPRODPLANSP => NFCPRODPLANSP,
+ NMAX_LEVEL => NMAX_LEVEL,
NOUT_OF_LIMIT => NOUT_OF_LIMIT);
/* Определяем уровень фильтра */
NLEVEL_FILTER := COALESCE(NLEVEL, NMAX_LEVEL);
@@ -2797,6 +2836,12 @@ create or replace package body PKG_P8PANELS_MECHREC as
DICNOMNS D,
DICMUNTS DM
where ((NCRN is null) or ((NCRN is not null) and (P.CRN = NCRN)))
+ and ((NPLANS_IDENT is null) or
+ ((NPLANS_IDENT is not null) and
+ (P.RN in (select SL.DOCUMENT
+ from SELECTLIST SL
+ where SL.IDENT = NPLANS_IDENT
+ and SL.UNITCODE = 'CostProductPlans'))))
and ((NFCPRODPLANSP is null) or
((NFCPRODPLANSP is not null) and
(P.RN = (select PRN from FCPRODPLANSP where RN = NFCPRODPLANSP))))
@@ -2917,14 +2962,48 @@ create or replace package body PKG_P8PANELS_MECHREC as
end loop;
/* Формируем список */
COUT := PKG_P8PANELS_VISUAL.TGANTT_TO_XML(RGANTT => RG);
+ /* Очищаем отмеченные планы */
+ P_SELECTLIST_CLEAR(NIDENT => NPLANS_IDENT);
+ exception
+ when others then
+ /* Очищаем отмеченные планы */
+ P_SELECTLIST_CLEAR(NIDENT => NPLANS_IDENT);
+ raise;
end FCPRODPLANSP_GET;
/* Инициализация каталогов раздела "Планы и отчеты производства изделий" для панели "Производственная программа" */
procedure FCPRODPLAN_PP_CTLG_INIT
(
- COUT out clob -- Список каталогов раздела "Планы и отчеты производства изделий"
+ COUT out clob -- Список каталогов раздела "Планы и отчеты производства изделий"
)
is
+ NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса
+
+ /* Считывание количества спецификаций плана */
+ function FCPRODPLANSP_COUNT_GET
+ (
+ NFCPRODPLAN in number -- Рег. номер плана
+ ) return number -- Количество документов спецификации плана
+ is
+ NRESULT PKG_STD.TNUMBER; -- Количество документов спецификации плана
+ begin
+ /* Считываем количество спецификаций */
+ begin
+ select count(T.RN)
+ into NRESULT
+ from FCPRODPLAN P,
+ FCPRODPLANSP T,
+ FINSTATE FS
+ where P.RN = NFCPRODPLAN
+ and T.PRN = P.RN
+ and T.MAIN_QUANT > 0;
+ exception
+ when others then
+ NRESULT := 0;
+ end;
+ /* Возвращаем результат */
+ return NRESULT;
+ end FCPRODPLANSP_COUNT_GET;
begin
/* Начинаем формирование XML */
PKG_XFAST.PROLOGUE(ITYPE => PKG_XFAST.CONTENT_);
@@ -2939,7 +3018,7 @@ create or replace package body PKG_P8PANELS_MECHREC as
where P.CRN = T.RN
and P.CATEGORY = NFCPRODPLAN_CATEGORY
and P.STATUS = NFCPRODPLAN_STATUS
- and P.COMPANY = GET_SESSION_COMPANY()
+ and P.COMPANY = NCOMPANY
and FS.RN = P.TYPE
and FS.CODE = SFCPRODPLAN_TYPE
and exists (select PSP.RN
@@ -2967,7 +3046,7 @@ create or replace package body PKG_P8PANELS_MECHREC as
where T.DOCNAME = 'CostProductPlans'
and T.SIGNS = 1
and T.DOCNAME = UL.UNITCODE
- and T.COMPANY = GET_SESSION_COMPANY()
+ and T.COMPANY = NCOMPANY
and (UL.SHOW_INACCESS_CTLG = 1 or exists
(select null from V_USERPRIV UP where UP.CATALOG = T.RN) or exists
(select null
@@ -2977,12 +3056,56 @@ create or replace package body PKG_P8PANELS_MECHREC as
start with T1.CRN = T.RN))
order by T.NAME asc)
loop
- /* Открываем план */
+ /* Открываем каталог плана */
PKG_XFAST.DOWN_NODE(SNAME => 'XFCPRODPLAN_CRNS');
- /* Описываем план */
+ /* Описываем каталог */
PKG_XFAST.ATTR(SNAME => 'NRN', NVALUE => REC.NRN);
PKG_XFAST.ATTR(SNAME => 'SNAME', SVALUE => REC.SNAME);
PKG_XFAST.ATTR(SNAME => 'NCOUNT_DOCS', NVALUE => REC.NCOUNT_DOCS);
+ /* Если содержит планы */
+ if (REC.NCOUNT_DOCS <> 0) then
+ /* Цикл по планам каталога */
+ for PLN in (select T.RN NRN,
+ trim(T.PREFIX) || '-' || trim(T.NUMB) SNAME
+ from FCPRODPLAN T,
+ FINSTATE FS
+ where T.CRN = REC.NRN
+ and T.CATEGORY = NFCPRODPLAN_CATEGORY
+ and T.STATUS = NFCPRODPLAN_STATUS
+ and T.COMPANY = NCOMPANY
+ and FS.RN = T.TYPE
+ and FS.CODE = SFCPRODPLAN_TYPE
+ and exists (select PSP.RN
+ from FCPRODPLANSP PSP
+ where PSP.PRN = T.RN
+ and PSP.MAIN_QUANT > 0)
+ and exists (select /*+ INDEX(UP I_USERPRIV_JUR_PERS_ROLEID) */
+ null
+ from USERPRIV UP
+ where UP.JUR_PERS = T.JUR_PERS
+ and UP.UNITCODE = 'CostProductPlans'
+ 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 = T.JUR_PERS
+ and UP.UNITCODE = 'CostProductPlans'
+ and UP.AUTHID = UTILIZER()))
+ loop
+ /* Открываем описание документов каталога */
+ PKG_XFAST.DOWN_NODE(SNAME => 'XCRN_PLANS');
+ /* Описываем план */
+ PKG_XFAST.ATTR(SNAME => 'NRN', NVALUE => PLN.NRN);
+ PKG_XFAST.ATTR(SNAME => 'SNAME', SVALUE => PLN.SNAME);
+ PKG_XFAST.ATTR(SNAME => 'NCOUNT_DOCS', NVALUE => FCPRODPLANSP_COUNT_GET(NFCPRODPLAN => PLN.NRN));
+ /* Закрываем документы каталога */
+ PKG_XFAST.UP();
+ end loop;
+ end if;
/* Закрываем план */
PKG_XFAST.UP();
end loop;