forked from CITKParus/P8-Panels
ЦИТК-968 - Доработка панели "Производственная программа"
This commit is contained in:
parent
11f29bcf0c
commit
47d6b0cdb1
@ -36,7 +36,8 @@ import {
|
|||||||
Card,
|
Card,
|
||||||
CardHeader,
|
CardHeader,
|
||||||
CardContent,
|
CardContent,
|
||||||
CardActions
|
CardActions,
|
||||||
|
Tooltip
|
||||||
} from "@mui/material"; //Интерфейсные элементы
|
} from "@mui/material"; //Интерфейсные элементы
|
||||||
import { BackEndСtx } from "../../context/backend"; //Контекст взаимодействия с сервером
|
import { BackEndСtx } from "../../context/backend"; //Контекст взаимодействия с сервером
|
||||||
import { MessagingСtx } from "../../context/messaging"; //Контекст сообщений
|
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 = "DREP_DATE";
|
||||||
const SORT_REP_DATE_TO = "DREP_DATE_TO";
|
const SORT_REP_DATE_TO = "DREP_DATE_TO";
|
||||||
|
|
||||||
|
//Максимальное количество элементов
|
||||||
|
const MAX_TASKS = 10000;
|
||||||
|
|
||||||
//Стили
|
//Стили
|
||||||
const STYLES = {
|
const STYLES = {
|
||||||
PLANS_FINDER: { marginTop: "10px", marginLeft: "10px", width: "93%" },
|
PLANS_FINDER: { marginTop: "10px", marginLeft: "10px", width: "93%" },
|
||||||
PLANS_CHECKBOX_HAVEDOCS: { alignContent: "space-around" },
|
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_ZERODOCS: { backgroundColor: "#ebecec" },
|
||||||
PLANS_LIST_ITEM_PRIMARY: { wordWrap: "break-word" },
|
PLANS_LIST_ITEM_PRIMARY: { wordWrap: "break-word" },
|
||||||
PLANS_LIST_ITEM_SECONDARY: { wordWrap: "break-word", fontSize: "0.6rem", textTransform: "uppercase" },
|
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_BUTTON: { position: "absolute", top: `calc(${APP_BAR_HEIGHT} + 16px)`, left: "16px" },
|
||||||
PLANS_DRAWER: {
|
PLANS_DRAWER: {
|
||||||
width: "350px",
|
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;
|
let num = (nCountDocs % 100) % 10;
|
||||||
//Документов
|
//Документов
|
||||||
@ -134,55 +152,146 @@ const formatCountDocs = nCountDocs => {
|
|||||||
return `${nCountDocs} ${DECLINATIONS[2]}`;
|
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 (
|
return (
|
||||||
<div>
|
<Box sx={STYLES.PLANS_LIST_CONTAINER}>
|
||||||
<TextField
|
<Box sx={STYLES.PLANS_LIST_FILTER_CONTAINER}>
|
||||||
sx={STYLES.PLANS_FINDER}
|
<TextField
|
||||||
name="planFilter"
|
sx={STYLES.PLANS_FINDER}
|
||||||
label="Каталог"
|
name="planFilter"
|
||||||
value={filter.ctlgName}
|
label="Каталог"
|
||||||
variant="standard"
|
value={filter.ctlgName}
|
||||||
fullWidth
|
variant="standard"
|
||||||
onChange={event => {
|
fullWidth
|
||||||
setFilter(pv => ({ ...pv, ctlgName: event.target.value }));
|
onChange={event => {
|
||||||
}}
|
setFilter(pv => ({ ...pv, ctlgName: event.target.value }));
|
||||||
></TextField>
|
}}
|
||||||
<FormGroup sx={STYLES.PLANS_CHECKBOX_HAVEDOCS}>
|
></TextField>
|
||||||
<FormControlLabel
|
<FormGroup sx={STYLES.PLANS_CHECKBOX_HAVEDOCS}>
|
||||||
control={<Checkbox checked={filter.haveDocs} onChange={event => setFilter(pv => ({ ...pv, haveDocs: event.target.checked }))} />}
|
<FormControlLabel
|
||||||
label="Только с планами"
|
control={
|
||||||
labelPlacement="end"
|
<Checkbox checked={filter.haveDocs} onChange={event => setFilter(pv => ({ ...pv, haveDocs: event.target.checked }))} />
|
||||||
/>
|
}
|
||||||
</FormGroup>
|
label="Только с планами"
|
||||||
<List>
|
labelPlacement="end"
|
||||||
{planCtlgs.map(p => (
|
/>
|
||||||
<ListItemButton
|
</FormGroup>
|
||||||
sx={p.NCOUNT_DOCS == 0 ? STYLES.PLANS_LIST_ITEM_ZERODOCS : null}
|
<List>
|
||||||
key={p.NRN}
|
{planCtlgs.map(ctlg => (
|
||||||
selected={p.NRN === selectedPlanCtlg}
|
<Box key={ctlg.NRN}>
|
||||||
onClick={() => (onClick ? onClick(p) : null)}
|
<ListItemButton
|
||||||
>
|
sx={ctlg.NCOUNT_DOCS == 0 ? STYLES.PLANS_LIST_ITEM_ZERODOCS : null}
|
||||||
<ListItemText
|
key={ctlg.NRN}
|
||||||
primary={<Typography sx={STYLES.PLANS_LIST_ITEM_PRIMARY}>{p.SNAME}</Typography>}
|
selected={ctlg.NRN === selectedPlanCtlg}
|
||||||
secondary={<Typography sx={STYLES.PLANS_LIST_ITEM_SECONDARY}>{formatCountDocs(p.NCOUNT_DOCS)}</Typography>}
|
onClick={() => (onCtlgClick ? onCtlgClick(ctlg) : null)}
|
||||||
/>
|
disabled={ctlg.NCOUNT_DOCS == 0}
|
||||||
</ListItemButton>
|
>
|
||||||
))}
|
<ListItemText
|
||||||
</List>
|
primary={<Typography sx={STYLES.PLANS_LIST_ITEM_PRIMARY}>{ctlg.SNAME}</Typography>}
|
||||||
</div>
|
secondary={<Typography sx={STYLES.PLANS_LIST_ITEM_SECONDARY}>{formatCountDocs(ctlg.NCOUNT_DOCS, 0)}</Typography>}
|
||||||
|
/>
|
||||||
|
</ListItemButton>
|
||||||
|
{ctlg.NRN === selectedPlanCtlg && ctlg.XCRN_PLANS.length > 1
|
||||||
|
? ctlg.XCRN_PLANS.map(plan => (
|
||||||
|
<ListItemButton
|
||||||
|
sx={plan.NCOUNT_DOCS == 0 ? STYLES.PLANS_LIST_ITEM_ZERODOCS : STYLES.PLANS_LIST_ITEM_PLAN}
|
||||||
|
key={plan.NRN}
|
||||||
|
disabled={plan.NCOUNT_DOCS == 0}
|
||||||
|
onClick={() => (onCtlgPlanClick ? onCtlgPlanClick(plan) : null)}
|
||||||
|
>
|
||||||
|
<ListItemText
|
||||||
|
sx={STYLES.PLANS_LIST_ITEM_PLAN_FIELD}
|
||||||
|
primary={<Typography sx={STYLES.PLANS_LIST_ITEM_PRIMARY}>{plan.SNAME}</Typography>}
|
||||||
|
secondary={
|
||||||
|
<Typography sx={STYLES.PLANS_LIST_ITEM_SECONDARY}>
|
||||||
|
{formatCountDocs(plan.NCOUNT_DOCS, 1)}
|
||||||
|
</Typography>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
{plan.NCOUNT_DOCS !== 0 ? <Checkbox checked={selectedPlans.includes(plan.NRN)} /> : null}
|
||||||
|
</ListItemButton>
|
||||||
|
))
|
||||||
|
: null}
|
||||||
|
</Box>
|
||||||
|
))}
|
||||||
|
</List>
|
||||||
|
</Box>
|
||||||
|
<Box sx={STYLES.PLANS_LIST_BUTTONS_CONTAINER}>
|
||||||
|
<Tooltip
|
||||||
|
title={
|
||||||
|
!selectedPlanCtlg
|
||||||
|
? "Не выбран каталог планов"
|
||||||
|
: selectedPlans.length === 0
|
||||||
|
? "Не выбраны планы каталога"
|
||||||
|
: selectedPlansElements > MAX_TASKS
|
||||||
|
? `Выбранные планы превышают максимум элементов (выбрано: ${selectedPlansElements}, максимум: ${MAX_TASKS})`
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Box>
|
||||||
|
<Button
|
||||||
|
sx={STYLES.PLANS_LIST_BUTTON}
|
||||||
|
variant="contained"
|
||||||
|
disabled={selectedPlans.length === 0 || selectedPlansElements > MAX_TASKS}
|
||||||
|
onClick={onCtlgPlansOk}
|
||||||
|
>
|
||||||
|
Применить
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
</Tooltip>
|
||||||
|
<Button sx={STYLES.PLANS_LIST_BUTTON} variant="contained" onClick={onCtlgPlansCancel}>
|
||||||
|
Отмена
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
//Контроль свойств - Список каталогов планов
|
//Контроль свойств - Список каталогов планов
|
||||||
PlanCtlgsList.propTypes = {
|
PlanCtlgsList.propTypes = {
|
||||||
planCtlgs: PropTypes.array,
|
planCtlgs: PropTypes.array,
|
||||||
|
selectedPlans: PropTypes.array,
|
||||||
selectedPlanCtlg: PropTypes.number,
|
selectedPlanCtlg: PropTypes.number,
|
||||||
onClick: PropTypes.func,
|
selectedPlansElements: PropTypes.number,
|
||||||
|
onCtlgClick: PropTypes.func,
|
||||||
|
onCtlgPlanClick: PropTypes.func,
|
||||||
filter: PropTypes.object,
|
filter: PropTypes.object,
|
||||||
setFilter: PropTypes.func
|
setFilter: PropTypes.func,
|
||||||
|
onCtlgPlansOk: PropTypes.func,
|
||||||
|
onCtlgPlansCancel: PropTypes.func
|
||||||
};
|
};
|
||||||
|
|
||||||
//Генерация диалога задачи
|
//Генерация диалога задачи
|
||||||
@ -251,6 +360,8 @@ const MechRecCostProdPlans = () => {
|
|||||||
showPlanList: false,
|
showPlanList: false,
|
||||||
planCtlgs: [],
|
planCtlgs: [],
|
||||||
planCtlgsLoaded: false,
|
planCtlgsLoaded: false,
|
||||||
|
selectedPlans: [],
|
||||||
|
selectedPlansElements: 0,
|
||||||
selectedPlanCtlgSpecsLoaded: false,
|
selectedPlanCtlgSpecsLoaded: false,
|
||||||
selectedPlanCtlg: null,
|
selectedPlanCtlg: null,
|
||||||
selectedPlanCtlgMaxLevel: null,
|
selectedPlanCtlgMaxLevel: null,
|
||||||
@ -258,6 +369,9 @@ const MechRecCostProdPlans = () => {
|
|||||||
selectedPlanCtlgOutOfLimit: 0,
|
selectedPlanCtlgOutOfLimit: 0,
|
||||||
selectedPlanCtlgSort: null,
|
selectedPlanCtlgSort: null,
|
||||||
selectedPlanCtlgMenuItems: null,
|
selectedPlanCtlgMenuItems: null,
|
||||||
|
loadedCtlg: null,
|
||||||
|
loadedPlans: [],
|
||||||
|
loadedElements: 0,
|
||||||
gantt: {},
|
gantt: {},
|
||||||
selectedTaskDetail: null,
|
selectedTaskDetail: null,
|
||||||
selectedTaskDetailType: null,
|
selectedTaskDetailType: null,
|
||||||
@ -273,7 +387,7 @@ const MechRecCostProdPlans = () => {
|
|||||||
const { InlineMsgInfo } = useContext(MessagingСtx);
|
const { InlineMsgInfo } = useContext(MessagingСtx);
|
||||||
|
|
||||||
//Подключение к контексту взаимодействия с сервером
|
//Подключение к контексту взаимодействия с сервером
|
||||||
const { executeStored } = useContext(BackEndСtx);
|
const { executeStored, SERV_DATA_TYPE_CLOB } = useContext(BackEndСtx);
|
||||||
|
|
||||||
//Подключение к контексту навигации
|
//Подключение к контексту навигации
|
||||||
const { getNavigationSearch } = useContext(NavigationCtx);
|
const { getNavigationSearch } = useContext(NavigationCtx);
|
||||||
@ -288,54 +402,28 @@ const MechRecCostProdPlans = () => {
|
|||||||
stored: "PKG_P8PANELS_MECHREC.FCPRODPLAN_PP_CTLG_INIT",
|
stored: "PKG_P8PANELS_MECHREC.FCPRODPLAN_PP_CTLG_INIT",
|
||||||
args: {},
|
args: {},
|
||||||
respArg: "COUT",
|
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 }));
|
setState(pv => ({ ...pv, init: true, planCtlgs: [...(data?.XFCPRODPLAN_CRNS || [])], planCtlgsLoaded: true }));
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [state.init, executeStored]);
|
}, [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(
|
const loadPlanCtglSpecs = useCallback(
|
||||||
async (level = null, sort = null) => {
|
async (level = null, sort = null) => {
|
||||||
const data = await executeStored({
|
const data = await executeStored({
|
||||||
stored: "PKG_P8PANELS_MECHREC.FCPRODPLANSP_GET",
|
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);
|
let doc = await parseProdPlanSpXML(data.COUT);
|
||||||
setState(pv => ({
|
setState(pv => ({
|
||||||
@ -344,21 +432,71 @@ const MechRecCostProdPlans = () => {
|
|||||||
selectedPlanCtlgLevel: level || level === 0 ? level : data.NMAX_LEVEL,
|
selectedPlanCtlgLevel: level || level === 0 ? level : data.NMAX_LEVEL,
|
||||||
selectedPlanCtlgOutOfLimit: data.NOUT_OF_LIMIT,
|
selectedPlanCtlgOutOfLimit: data.NOUT_OF_LIMIT,
|
||||||
selectedPlanCtlgSort: sort,
|
selectedPlanCtlgSort: sort,
|
||||||
selectedPlanCtlgMenuItems: state.selectedPlanCtlgMenuItems
|
selectedPlanCtlgMenuItems: [...Array(data.NMAX_LEVEL).keys()].map(el => el + 1),
|
||||||
? state.selectedPlanCtlgMenuItems
|
|
||||||
: [...Array(data.NMAX_LEVEL).keys()].map(el => el + 1),
|
|
||||||
selectedPlanCtlgSpecsLoaded: true,
|
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
|
// 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 => {
|
const handleCtlgClick = project => {
|
||||||
if (state.selectedPlanCtlg != project.NRN) selectPlan(project.NRN);
|
//Если этот каталог не был выбран
|
||||||
else unselectPlan();
|
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(() => {
|
useEffect(() => {
|
||||||
if (state.selectedPlanCtlg || state.planSpec) loadPlanCtglSpecs(null, SORT_REP_DATE_TO);
|
if (state.planSpec) loadPlanCtglSpecs(null, SORT_REP_DATE_TO);
|
||||||
}, [state.selectedPlanCtlg, state.planSpec, loadPlanCtglSpecs]);
|
}, [state.planSpec, loadPlanCtglSpecs]);
|
||||||
|
|
||||||
//Выбор уровня
|
//Выбор уровня
|
||||||
const handleChangeSelectLevel = selectedLevel => {
|
const handleChangeSelectLevel = selectedLevel => {
|
||||||
@ -415,18 +553,18 @@ const MechRecCostProdPlans = () => {
|
|||||||
<Fab variant="extended" sx={STYLES.PLANS_BUTTON} onClick={() => setState(pv => ({ ...pv, showPlanList: !pv.showPlanList }))}>
|
<Fab variant="extended" sx={STYLES.PLANS_BUTTON} onClick={() => setState(pv => ({ ...pv, showPlanList: !pv.showPlanList }))}>
|
||||||
Каталоги планов
|
Каталоги планов
|
||||||
</Fab>
|
</Fab>
|
||||||
<Drawer
|
<Drawer anchor={"left"} open={state.showPlanList} onClose={handleSelectedPlansCancel} sx={STYLES.PLANS_DRAWER}>
|
||||||
anchor={"left"}
|
|
||||||
open={state.showPlanList}
|
|
||||||
onClose={() => setState(pv => ({ ...pv, showPlanList: false }))}
|
|
||||||
sx={STYLES.PLANS_DRAWER}
|
|
||||||
>
|
|
||||||
<PlanCtlgsList
|
<PlanCtlgsList
|
||||||
planCtlgs={filteredPlanCtgls}
|
planCtlgs={filteredPlanCtgls}
|
||||||
|
selectedPlans={state.selectedPlans}
|
||||||
selectedPlanCtlg={state.selectedPlanCtlg}
|
selectedPlanCtlg={state.selectedPlanCtlg}
|
||||||
|
selectedPlansElements={state.selectedPlansElements}
|
||||||
filter={filter}
|
filter={filter}
|
||||||
setFilter={setFilter}
|
setFilter={setFilter}
|
||||||
onClick={handleProjectClick}
|
onCtlgClick={handleCtlgClick}
|
||||||
|
onCtlgPlanClick={handleCtlgPlanClick}
|
||||||
|
onCtlgPlansOk={handleSelectedPlansOk}
|
||||||
|
onCtlgPlansCancel={handleSelectedPlansCancel}
|
||||||
/>
|
/>
|
||||||
</Drawer>
|
</Drawer>
|
||||||
</>
|
</>
|
||||||
@ -508,14 +646,14 @@ const MechRecCostProdPlans = () => {
|
|||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
) : !state.selectedPlanCtlg ? (
|
) : !state.loadedCtlg ? (
|
||||||
<Box pt={3}>
|
<Box pt={3}>
|
||||||
<InlineMsgInfo
|
<InlineMsgInfo
|
||||||
okBtn={false}
|
okBtn={false}
|
||||||
text={
|
text={
|
||||||
state.planSpec
|
state.planSpec
|
||||||
? "Загружаю график для выбранной позиции плана..."
|
? "Загружаю график для выбранной позиции плана..."
|
||||||
: "Укажите каталог планов для отображения их спецификаций"
|
: "Укажите каталог планов или планы для отображения их спецификаций"
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
@ -81,6 +81,7 @@ create or replace package PKG_P8PANELS_MECHREC as
|
|||||||
procedure FCPRODPLANSP_GET
|
procedure FCPRODPLANSP_GET
|
||||||
(
|
(
|
||||||
NCRN in number, -- Рег. номер каталога
|
NCRN in number, -- Рег. номер каталога
|
||||||
|
CFCPRODPLANS in clob, -- Список отмеченных планов (разделитель - ";")
|
||||||
NFCPRODPLANSP in number, -- Рег. номер позиции спецификации
|
NFCPRODPLANSP in number, -- Рег. номер позиции спецификации
|
||||||
NLEVEL in number := null, -- Уровень отбора
|
NLEVEL in number := null, -- Уровень отбора
|
||||||
SSORT_FIELD in varchar2 := 'DREP_DATE_TO', -- Поле сортировки
|
SSORT_FIELD in varchar2 := 'DREP_DATE_TO', -- Поле сортировки
|
||||||
@ -513,6 +514,28 @@ create or replace package body PKG_P8PANELS_MECHREC as
|
|||||||
end;
|
end;
|
||||||
end UTL_FCROUTLST_GET;
|
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
|
function UTL_SUBDIV_RN_GET
|
||||||
(
|
(
|
||||||
@ -2259,6 +2282,7 @@ create or replace package body PKG_P8PANELS_MECHREC as
|
|||||||
procedure FCPRODPLANSP_GET
|
procedure FCPRODPLANSP_GET
|
||||||
(
|
(
|
||||||
NCRN in number, -- Рег. номер каталога
|
NCRN in number, -- Рег. номер каталога
|
||||||
|
CFCPRODPLANS in clob, -- Список отмеченных планов (разделитель - ";")
|
||||||
NFCPRODPLANSP in number, -- Рег. номер позиции спецификации
|
NFCPRODPLANSP in number, -- Рег. номер позиции спецификации
|
||||||
NLEVEL in number := null, -- Уровень отбора
|
NLEVEL in number := null, -- Уровень отбора
|
||||||
SSORT_FIELD in varchar2 := 'DREP_DATE_TO', -- Поле сортировки
|
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(); -- Организация сеанса
|
NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса
|
||||||
NTASK_CLASS PKG_STD.TNUMBER; -- Класс задачи (см. константы NCLASS_*)
|
NTASK_CLASS PKG_STD.TNUMBER; -- Класс задачи (см. константы NCLASS_*)
|
||||||
NLEVEL_FILTER PKG_STD.TNUMBER; -- Уровень для фильтра
|
NLEVEL_FILTER PKG_STD.TNUMBER; -- Уровень для фильтра
|
||||||
|
NPLANS_IDENT PKG_STD.TREF; -- Идентификатор отмеченных планов
|
||||||
|
|
||||||
/* Объединение значений в строковое представление */
|
/* Объединение значений в строковое представление */
|
||||||
function MAKE_INFO
|
function MAKE_INFO
|
||||||
@ -2308,6 +2333,7 @@ create or replace package body PKG_P8PANELS_MECHREC as
|
|||||||
procedure PRODPLAN_MAX_LEVEL_GET
|
procedure PRODPLAN_MAX_LEVEL_GET
|
||||||
(
|
(
|
||||||
NCRN in number, -- Рег. номер каталога планов
|
NCRN in number, -- Рег. номер каталога планов
|
||||||
|
NPLANS_IDENT in number, -- Идентификатор отмеченных планов
|
||||||
NFCPRODPLANSP in number, -- Рег. номер позиции спецификации
|
NFCPRODPLANSP in number, -- Рег. номер позиции спецификации
|
||||||
NMAX_LEVEL out number, -- Максимальный уровень иерархии
|
NMAX_LEVEL out number, -- Максимальный уровень иерархии
|
||||||
NOUT_OF_LIMIT out number -- Признак превышения лимита (0 - нет, 1 - да)
|
NOUT_OF_LIMIT out number -- Признак превышения лимита (0 - нет, 1 - да)
|
||||||
@ -2328,6 +2354,12 @@ create or replace package body PKG_P8PANELS_MECHREC as
|
|||||||
FCPRODPLANSP T,
|
FCPRODPLANSP T,
|
||||||
FINSTATE FS
|
FINSTATE FS
|
||||||
where ((NCRN is null) or ((NCRN is not null) and (P.CRN = NCRN)))
|
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
|
and ((NFCPRODPLANSP is null) or
|
||||||
((NFCPRODPLANSP is not null) and
|
((NFCPRODPLANSP is not null) and
|
||||||
(P.RN = (select PRN from FCPRODPLANSP where RN = NFCPRODPLANSP))))
|
(P.RN = (select PRN from FCPRODPLANSP where RN = NFCPRODPLANSP))))
|
||||||
@ -2711,12 +2743,18 @@ create or replace package body PKG_P8PANELS_MECHREC as
|
|||||||
begin
|
begin
|
||||||
/* Определяем заголовок плана */
|
/* Определяем заголовок плана */
|
||||||
if (NCRN is not null) then
|
if (NCRN is not null) then
|
||||||
|
/* Считываем каталог */
|
||||||
FIND_ACATALOG_RN(NFLAG_SMART => 0,
|
FIND_ACATALOG_RN(NFLAG_SMART => 0,
|
||||||
NCOMPANY => NCOMPANY,
|
NCOMPANY => NCOMPANY,
|
||||||
NVERSION => null,
|
NVERSION => null,
|
||||||
SUNITCODE => 'CostProductPlans',
|
SUNITCODE => 'CostProductPlans',
|
||||||
NRN => NCRN,
|
NRN => NCRN,
|
||||||
SNAME => SPLAN_TITLE);
|
SNAME => SPLAN_TITLE);
|
||||||
|
/* Если есть выбранные планы */
|
||||||
|
if (CFCPRODPLANS is not null) then
|
||||||
|
/* Инициализируем отмеченные планы в селектлисте */
|
||||||
|
UTL_FCPRODPLAN_IDENT_INIT(CFCPRODPLANS => CFCPRODPLANS, NIDENT => NPLANS_IDENT);
|
||||||
|
end if;
|
||||||
else
|
else
|
||||||
if (NFCPRODPLANSP is not null) then
|
if (NFCPRODPLANSP is not null) then
|
||||||
begin
|
begin
|
||||||
@ -2750,9 +2788,10 @@ create or replace package body PKG_P8PANELS_MECHREC as
|
|||||||
/* Инициализируем описания цветов */
|
/* Инициализируем описания цветов */
|
||||||
TASK_COLORS_INIT(RG => RG);
|
TASK_COLORS_INIT(RG => RG);
|
||||||
/* Определяем максимальный уровень иерархии */
|
/* Определяем максимальный уровень иерархии */
|
||||||
PRODPLAN_MAX_LEVEL_GET(NCRN => NCRN,
|
PRODPLAN_MAX_LEVEL_GET(NCRN => NCRN,
|
||||||
NFCPRODPLANSP => NFCPRODPLANSP,
|
NPLANS_IDENT => NPLANS_IDENT,
|
||||||
NMAX_LEVEL => NMAX_LEVEL,
|
NFCPRODPLANSP => NFCPRODPLANSP,
|
||||||
|
NMAX_LEVEL => NMAX_LEVEL,
|
||||||
NOUT_OF_LIMIT => NOUT_OF_LIMIT);
|
NOUT_OF_LIMIT => NOUT_OF_LIMIT);
|
||||||
/* Определяем уровень фильтра */
|
/* Определяем уровень фильтра */
|
||||||
NLEVEL_FILTER := COALESCE(NLEVEL, NMAX_LEVEL);
|
NLEVEL_FILTER := COALESCE(NLEVEL, NMAX_LEVEL);
|
||||||
@ -2797,6 +2836,12 @@ create or replace package body PKG_P8PANELS_MECHREC as
|
|||||||
DICNOMNS D,
|
DICNOMNS D,
|
||||||
DICMUNTS DM
|
DICMUNTS DM
|
||||||
where ((NCRN is null) or ((NCRN is not null) and (P.CRN = NCRN)))
|
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
|
and ((NFCPRODPLANSP is null) or
|
||||||
((NFCPRODPLANSP is not null) and
|
((NFCPRODPLANSP is not null) and
|
||||||
(P.RN = (select PRN from FCPRODPLANSP where RN = NFCPRODPLANSP))))
|
(P.RN = (select PRN from FCPRODPLANSP where RN = NFCPRODPLANSP))))
|
||||||
@ -2917,14 +2962,48 @@ create or replace package body PKG_P8PANELS_MECHREC as
|
|||||||
end loop;
|
end loop;
|
||||||
/* Формируем список */
|
/* Формируем список */
|
||||||
COUT := PKG_P8PANELS_VISUAL.TGANTT_TO_XML(RGANTT => RG);
|
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;
|
end FCPRODPLANSP_GET;
|
||||||
|
|
||||||
/* Инициализация каталогов раздела "Планы и отчеты производства изделий" для панели "Производственная программа" */
|
/* Инициализация каталогов раздела "Планы и отчеты производства изделий" для панели "Производственная программа" */
|
||||||
procedure FCPRODPLAN_PP_CTLG_INIT
|
procedure FCPRODPLAN_PP_CTLG_INIT
|
||||||
(
|
(
|
||||||
COUT out clob -- Список каталогов раздела "Планы и отчеты производства изделий"
|
COUT out clob -- Список каталогов раздела "Планы и отчеты производства изделий"
|
||||||
)
|
)
|
||||||
is
|
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
|
begin
|
||||||
/* Начинаем формирование XML */
|
/* Начинаем формирование XML */
|
||||||
PKG_XFAST.PROLOGUE(ITYPE => PKG_XFAST.CONTENT_);
|
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
|
where P.CRN = T.RN
|
||||||
and P.CATEGORY = NFCPRODPLAN_CATEGORY
|
and P.CATEGORY = NFCPRODPLAN_CATEGORY
|
||||||
and P.STATUS = NFCPRODPLAN_STATUS
|
and P.STATUS = NFCPRODPLAN_STATUS
|
||||||
and P.COMPANY = GET_SESSION_COMPANY()
|
and P.COMPANY = NCOMPANY
|
||||||
and FS.RN = P.TYPE
|
and FS.RN = P.TYPE
|
||||||
and FS.CODE = SFCPRODPLAN_TYPE
|
and FS.CODE = SFCPRODPLAN_TYPE
|
||||||
and exists (select PSP.RN
|
and exists (select PSP.RN
|
||||||
@ -2967,7 +3046,7 @@ create or replace package body PKG_P8PANELS_MECHREC as
|
|||||||
where T.DOCNAME = 'CostProductPlans'
|
where T.DOCNAME = 'CostProductPlans'
|
||||||
and T.SIGNS = 1
|
and T.SIGNS = 1
|
||||||
and T.DOCNAME = UL.UNITCODE
|
and T.DOCNAME = UL.UNITCODE
|
||||||
and T.COMPANY = GET_SESSION_COMPANY()
|
and T.COMPANY = NCOMPANY
|
||||||
and (UL.SHOW_INACCESS_CTLG = 1 or exists
|
and (UL.SHOW_INACCESS_CTLG = 1 or exists
|
||||||
(select null from V_USERPRIV UP where UP.CATALOG = T.RN) or exists
|
(select null from V_USERPRIV UP where UP.CATALOG = T.RN) or exists
|
||||||
(select null
|
(select null
|
||||||
@ -2977,12 +3056,56 @@ create or replace package body PKG_P8PANELS_MECHREC as
|
|||||||
start with T1.CRN = T.RN))
|
start with T1.CRN = T.RN))
|
||||||
order by T.NAME asc)
|
order by T.NAME asc)
|
||||||
loop
|
loop
|
||||||
/* Открываем план */
|
/* Открываем каталог плана */
|
||||||
PKG_XFAST.DOWN_NODE(SNAME => 'XFCPRODPLAN_CRNS');
|
PKG_XFAST.DOWN_NODE(SNAME => 'XFCPRODPLAN_CRNS');
|
||||||
/* Описываем план */
|
/* Описываем каталог */
|
||||||
PKG_XFAST.ATTR(SNAME => 'NRN', NVALUE => REC.NRN);
|
PKG_XFAST.ATTR(SNAME => 'NRN', NVALUE => REC.NRN);
|
||||||
PKG_XFAST.ATTR(SNAME => 'SNAME', SVALUE => REC.SNAME);
|
PKG_XFAST.ATTR(SNAME => 'SNAME', SVALUE => REC.SNAME);
|
||||||
PKG_XFAST.ATTR(SNAME => 'NCOUNT_DOCS', NVALUE => REC.NCOUNT_DOCS);
|
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();
|
PKG_XFAST.UP();
|
||||||
end loop;
|
end loop;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user