ЦИТК-794 - Доработка панели "Производственная программа"

This commit is contained in:
Mikhail Chechnev 2024-02-15 14:51:16 +03:00 committed by GitHub
commit adb3fe7746
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 536 additions and 336 deletions

View File

@ -14,10 +14,10 @@ import React from "react"; //Классы React
//----------- //-----------
//Клиентский отбор загруженных планов по поисковой фразе //Клиентский отбор загруженных планов по поисковой фразе
export const useFilteredPlans = (plans, filter) => { export const useFilteredPlanCtlgs = (planCtlgs, filter) => {
const filteredPlans = React.useMemo(() => { const filteredPlanCtlgs = React.useMemo(() => {
return plans.filter(project => project.SDOC_INFO.toLowerCase().includes(filter)); return planCtlgs.filter(catalog => catalog.SNAME.toString().toLowerCase().includes(filter));
}, [plans, filter]); }, [planCtlgs, filter]);
return filteredPlans; return filteredPlanCtlgs;
}; };

View File

@ -12,18 +12,21 @@ import PropTypes from "prop-types"; //Контроль свойств компо
import { Drawer, Fab, Box, List, ListItemButton, ListItemText, Typography, Grid, TextField, Select, MenuItem, InputLabel } from "@mui/material"; //Интерфейсные элементы import { Drawer, Fab, Box, List, ListItemButton, ListItemText, Typography, Grid, TextField, Select, MenuItem, InputLabel } 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"; //Контекст сообщений
import { ApplicationСtx } from "../../context/application"; //Контекст приложения
import { P8P_GANTT_CONFIG_PROPS } from "../../config_wrapper"; //Подключение компонентов к настройкам приложения import { P8P_GANTT_CONFIG_PROPS } from "../../config_wrapper"; //Подключение компонентов к настройкам приложения
import { P8PGantt } from "../../components/p8p_gantt"; //Диаграмма Ганта import { P8PGantt } from "../../components/p8p_gantt"; //Диаграмма Ганта
import { xml2JSON, formatDateJSONDateOnly } from "../../core/utils"; //Вспомогательные функции import { xml2JSON, formatDateJSONDateOnly } from "../../core/utils"; //Вспомогательные функции
import { useFilteredPlans } from "./hooks"; //Вспомогательные хуки import { useFilteredPlanCtlgs } from "./hooks"; //Вспомогательные хуки
//--------- //---------
//Константы //Константы
//--------- //---------
//Поля сортировки
const SORT_REP_DATE = "DREP_DATE";
const SORT_REP_DATE_TO = "DREP_DATE_TO";
//Высота диаграммы Ганта //Высота диаграммы Ганта
const GANTT_HEIGHT = "650px"; const GANTT_HEIGHT = "75vh";
//Ширина диаграммы Ганта //Ширина диаграммы Ганта
const GANTT_WIDTH = "98vw"; const GANTT_WIDTH = "98vw";
@ -56,8 +59,8 @@ const parseProdPlanSpXML = async xmlDoc => {
return data.XDATA; return data.XDATA;
}; };
//Список планов //Список каталогов планов
const PlansList = ({ plans = [], selectedPlan, filter, setFilter, onClick } = {}) => { const PlanCtlgsList = ({ planCtlgs = [], selectedPlanCtlg, filter, setFilter, onClick } = {}) => {
//Генерация содержимого //Генерация содержимого
return ( return (
<div> <div>
@ -73,9 +76,9 @@ const PlansList = ({ plans = [], selectedPlan, filter, setFilter, onClick } = {}
}} }}
></TextField> ></TextField>
<List> <List>
{plans.map(p => ( {planCtlgs.map(p => (
<ListItemButton key={p.NRN} selected={p.NRN === selectedPlan} onClick={() => (onClick ? onClick(p) : null)}> <ListItemButton key={p.NRN} selected={p.NRN === selectedPlanCtlg} onClick={() => (onClick ? onClick(p) : null)}>
<ListItemText primary={<Typography sx={STYLES.PLANS_LIST_ITEM_PRIMARY}>{p.SDOC_INFO}</Typography>} /> <ListItemText primary={<Typography sx={STYLES.PLANS_LIST_ITEM_PRIMARY}>{p.SNAME}</Typography>} />
</ListItemButton> </ListItemButton>
))} ))}
</List> </List>
@ -83,10 +86,10 @@ const PlansList = ({ plans = [], selectedPlan, filter, setFilter, onClick } = {}
); );
}; };
//Контроль свойств - Список планов //Контроль свойств - Список каталогов планов
PlansList.propTypes = { PlanCtlgsList.propTypes = {
plans: PropTypes.array, planCtlgs: PropTypes.array,
selectedPlan: PropTypes.number, selectedPlanCtlg: PropTypes.number,
onClick: PropTypes.func, onClick: PropTypes.func,
filter: PropTypes.string, filter: PropTypes.string,
setFilter: PropTypes.func setFilter: PropTypes.func
@ -102,23 +105,21 @@ const MechRecCostProdPlans = () => {
let [state, setState] = useState({ let [state, setState] = useState({
init: false, init: false,
showPlanList: false, showPlanList: false,
plans: [], planCtlgs: [],
plansLoaded: false, planCtlgsLoaded: false,
selectedPlanSpecsLoaded: false, selectedPlanCtlgSpecsLoaded: false,
selectedPlan: null, selectedPlanCtlg: null,
selectedPlanMaxLevel: null, selectedPlanCtlgMaxLevel: null,
selectedPlanLevel: null, selectedPlanCtlgLevel: null,
selectedPlanMenuItems: null, selectedPlanCtlgSort: null,
selectedPlanGanttDef: {}, selectedPlanCtlgMenuItems: null,
selectedPlanSpecs: [] selectedPlanCtlgGanttDef: {},
selectedPlanCtlgSpecs: []
}); });
const [filter, setFilter] = useState(""); const [filter, setFilter] = useState("");
const filteredPlans = useFilteredPlans(state.plans, filter); const filteredPlanCtgls = useFilteredPlanCtlgs(state.planCtlgs, filter);
//Подключение к контексту приложения
const { pOnlineShowDocument } = useContext(ApplicationСtx);
//Подключение к контексту сообщений //Подключение к контексту сообщений
const { InlineMsgInfo } = useContext(MessagingСtx); const { InlineMsgInfo } = useContext(MessagingСtx);
@ -126,106 +127,110 @@ const MechRecCostProdPlans = () => {
//Подключение к контексту взаимодействия с сервером //Подключение к контексту взаимодействия с сервером
const { executeStored } = useContext(BackEndСtx); const { executeStored } = useContext(BackEndСtx);
// Инициализация планов // Инициализация каталогов планов
const initPlans = useCallback(async () => { const initPlanCtlgs = useCallback(async () => {
if (!state.init) { if (!state.init) {
const data = await executeStored({ const data = await executeStored({
stored: "PKG_P8PANELS_MECHREC.PRODPLAN_INIT", stored: "PKG_P8PANELS_MECHREC.ACATALOG_INIT",
args: {}, args: {},
respArg: "COUT", respArg: "COUT",
isArray: name => name === "XFCPRODPLANS" isArray: name => name === "XFCPRODPLAN_CRNS"
}); });
setState(pv => ({ ...pv, init: true, plans: [...(data?.XFCPRODPLANS || [])], plansLoaded: 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 => { const selectPlan = project => {
setState(pv => ({ setState(pv => ({
...pv, ...pv,
selectedPlan: project, selectedPlanCtlg: project,
selectedPlanSpecsLoaded: false, selectedPlanCtlgSpecsLoaded: false,
selectedPlanMaxLevel: null, selectedPlanCtlgMaxLevel: null,
selectedPlanLevel: null, selectedPlanCtlgLevel: null,
selectedPlanMenuItems: null, selectedPlanCtlgSort: null,
selectedPlanSpecs: [], selectedPlanCtlgMenuItems: null,
selectedPlanGanttDef: {}, selectedPlanCtlgSpecs: [],
selectedPlanCtlgGanttDef: {},
showPlanList: false showPlanList: false
})); }));
}; };
//Сброс выбора плана //Сброс выбора каталога планов
const unselectPlan = () => const unselectPlan = () =>
setState(pv => ({ setState(pv => ({
...pv, ...pv,
selectedPlanSpecsLoaded: false, selectedPlanCtlgSpecsLoaded: false,
selectedPlan: null, selectedPlanCtlg: null,
selectedPlanMaxLevel: null, selectedPlanCtlgMaxLevel: null,
selectedPlanLevel: null, selectedPlanCtlgLevel: null,
selectedPlanMenuItems: null, selectedPlanCtlgSort: null,
selectedPlanSpecs: [], selectedPlanCtlgMenuItems: null,
selectedPlanGanttDef: {}, selectedPlanCtlgSpecs: [],
selectedPlanCtlgGanttDef: {},
showPlanList: false showPlanList: false
})); }));
//Загрузка списка спецификаций плана //Загрузка списка спецификаций каталога планов
const loadPlanSpecs = useCallback( const loadPlanCtglSpecs = useCallback(
async (level = 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: { NFCPRODPLAN: state.selectedPlan, NLEVEL: level } args: { NCRN: state.selectedPlanCtlg, NLEVEL: level, SSORT_FIELD: sort }
}); });
let doc = await parseProdPlanSpXML(data.COUT); let doc = await parseProdPlanSpXML(data.COUT);
setState(pv => ({ setState(pv => ({
...pv, ...pv,
selectedPlanMaxLevel: data.NMAX_LEVEL, selectedPlanCtlgMaxLevel: data.NMAX_LEVEL,
selectedPlanLevel: level || level === 0 ? level : data.NMAX_LEVEL, selectedPlanCtlgLevel: level || level === 0 ? level : data.NMAX_LEVEL,
selectedPlanMenuItems: state.selectedPlanMenuItems selectedPlanCtlgSort: sort,
? state.selectedPlanMenuItems selectedPlanCtlgMenuItems: state.selectedPlanCtlgMenuItems
? state.selectedPlanCtlgMenuItems
: [...Array(data.NMAX_LEVEL).keys()].map(el => el + 1), : [...Array(data.NMAX_LEVEL).keys()].map(el => el + 1),
selectedPlanSpecsLoaded: true, selectedPlanCtlgSpecsLoaded: true,
selectedPlanGanttDef: doc.XGANTT_DEF ? { ...doc.XGANTT_DEF } : {}, selectedPlanCtlgGanttDef: doc.XGANTT_DEF ? { ...doc.XGANTT_DEF } : {},
selectedPlanSpecs: [...(doc?.XGANTT_TASKS || [])] selectedPlanCtlgSpecs: [...(doc?.XGANTT_TASKS || [])]
})); }));
}, },
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
[executeStored, state.ident, state.selectedPlan] [executeStored, state.ident, state.selectedPlanCtlg]
); );
//Обработка нажатия на элемент в списке планов //Обработка нажатия на элемент в списке каталогов планов
const handleProjectClick = project => { const handleProjectClick = project => {
if (state.selectedPlan != project.NRN) selectPlan(project.NRN); if (state.selectedPlanCtlg != project.NRN) selectPlan(project.NRN);
else unselectPlan(); else unselectPlan();
}; };
//Отработка нажатия на заголовок плана
const handleTitleClick = () => {
state.selectedPlan ? pOnlineShowDocument({ unitCode: "CostProductPlans", document: state.selectedPlan }) : null;
};
//При подключении компонента к странице //При подключении компонента к странице
useEffect(() => { useEffect(() => {
initPlans(); initPlanCtlgs();
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, []); }, []);
//При смене выбранного плана //При смене выбранного каталога плана
useEffect(() => { useEffect(() => {
if (state.selectedPlan) loadPlanSpecs(); if (state.selectedPlanCtlg) loadPlanCtglSpecs(null, SORT_REP_DATE_TO);
}, [state.selectedPlan, loadPlanSpecs]); }, [state.selectedPlanCtlg, loadPlanCtglSpecs]);
//Выбор уровня //Выбор уровня
const handleChangeSelectList = selectedLevel => { const handleChangeSelectLevel = selectedLevel => {
loadPlanSpecs(selectedLevel); loadPlanCtglSpecs(selectedLevel, state.selectedPlanCtlgSort);
setState(pv => ({ ...pv, selectedPlanLevel: selectedLevel })); setState(pv => ({ ...pv, selectedPlanCtlgLevel: selectedLevel }));
};
//Выбор сортировки
const handleChangeSelectSort = selectedSort => {
loadPlanCtglSpecs(state.selectedPlanCtlgLevel, selectedSort);
setState(pv => ({ ...pv, selectedPlanCtlgSort: selectedSort }));
}; };
//Генерация содержимого //Генерация содержимого
return ( return (
<Box p={2}> <Box p={2}>
<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"} anchor={"left"}
@ -233,9 +238,9 @@ const MechRecCostProdPlans = () => {
onClose={() => setState(pv => ({ ...pv, showPlanList: false }))} onClose={() => setState(pv => ({ ...pv, showPlanList: false }))}
sx={STYLES.PLANS_DRAWER} sx={STYLES.PLANS_DRAWER}
> >
<PlansList <PlanCtlgsList
plans={filteredPlans} planCtlgs={filteredPlanCtgls}
selectedPlan={state.selectedPlan} selectedPlanCtlg={state.selectedPlanCtlg}
filter={filter} filter={filter}
setFilter={setFilter} setFilter={setFilter}
onClick={handleProjectClick} onClick={handleProjectClick}
@ -244,44 +249,66 @@ const MechRecCostProdPlans = () => {
{state.init == true ? ( {state.init == true ? (
<Grid container spacing={1}> <Grid container spacing={1}>
<Grid item xs={12}> <Grid item xs={12}>
{state.selectedPlanSpecsLoaded ? ( {state.selectedPlanCtlgSpecsLoaded ? (
state.selectedPlanSpecs.length === 0 ? ( state.selectedPlanCtlgSpecs.length === 0 ? (
<InlineMsgInfo okBtn={false} text={"В плане отсутствуют записи спецификации"} /> <InlineMsgInfo okBtn={false} text={"В каталоге планов отсутствуют записи спецификации"} />
) : ( ) : (
<Box sx={STYLES.GANTT_CONTAINER} p={1}> <Box sx={STYLES.GANTT_CONTAINER} p={1}>
{state.selectedPlanMaxLevel ? ( {state.selectedPlanCtlgMaxLevel ? (
<Box sx={{ float: "right" }}> <Box sx={{ display: "table", float: "right" }}>
<InputLabel id="demo-simple-select-label">Уровень</InputLabel> <Box sx={{ display: "table-cell", verticalAlign: "middle" }}>
<InputLabel id="select-label-sort">Сортировка</InputLabel>
<Select <Select
labelId="demo-simple-select-label" labelId="select-label-sort"
id="demo-simple-select" id="select-sort"
value={state.selectedPlanLevel} value={state.selectedPlanCtlgSort}
label="Сортировка"
onChange={event => {
handleChangeSelectSort(event.target.value);
}}
defaultValue={state.selectedPlanCtlgLevel}
>
<MenuItem value={SORT_REP_DATE_TO} key="1">
Дата выпуска
</MenuItem>
<MenuItem value={SORT_REP_DATE} key="2">
Дата запуска
</MenuItem>
</Select>
</Box>
<Box sx={{ display: "table-cell", verticalAlign: "middle", paddingLeft: "15px" }}>
<InputLabel id="select-label-level">До уровня</InputLabel>
<Select
labelId="select-label-level"
id="select-level"
value={state.selectedPlanCtlgLevel}
label="Уровень" label="Уровень"
onChange={event => { onChange={event => {
handleChangeSelectList(event.target.value); handleChangeSelectLevel(event.target.value);
}} }}
defaultValue={state.selectedPlanLevel} defaultValue={state.selectedPlanCtlgLevel}
> >
{state.selectedPlanMenuItems.map(el => ( {state.selectedPlanCtlgMenuItems.map(el => (
<MenuItem value={el} key={el}> <MenuItem value={el} key={el}>
{el} {el}
</MenuItem> </MenuItem>
))} ))}
</Select> </Select>
</Box> </Box>
) : null} </Box>
) : // </Grid>
null}
<P8PGantt <P8PGantt
{...P8P_GANTT_CONFIG_PROPS} {...P8P_GANTT_CONFIG_PROPS}
{...state.selectedPlanGanttDef} {...state.selectedPlanCtlgGanttDef}
height={GANTT_HEIGHT} height={GANTT_HEIGHT}
onTitleClick={handleTitleClick}
titleStyle={STYLES.GANTT_TITLE} titleStyle={STYLES.GANTT_TITLE}
tasks={state.selectedPlanSpecs} tasks={state.selectedPlanCtlgSpecs}
/> />
</Box> </Box>
) )
) : !state.selectedPlan ? ( ) : !state.selectedPlanCtlg ? (
<InlineMsgInfo okBtn={false} text={"Укажите план для отображения его спецификации"} /> <InlineMsgInfo okBtn={false} text={"Укажите каталог планов для отображения их спецификаций"} />
) : null} ) : null}
</Grid> </Grid>
</Grid> </Grid>

View File

@ -3,16 +3,17 @@ create or replace package PKG_P8PANELS_MECHREC as
/* Получение списка спецификаций планов и отчетов производства изделий для диаграммы Ганта */ /* Получение списка спецификаций планов и отчетов производства изделий для диаграммы Ганта */
procedure FCPRODPLANSP_GET procedure FCPRODPLANSP_GET
( (
NFCPRODPLAN in number, -- Рег. номер родителя NCRN in number, -- Рег. номер каталога
NLEVEL in number := null, -- Уровень отбора NLEVEL in number := null, -- Уровень отбора
SSORT_FIELD in varchar2 := 'DREP_DATE_TO', -- Поле сортировки
COUT out clob, -- Список проектов COUT out clob, -- Список проектов
NMAX_LEVEL out number -- Максимальный уровень иерархии NMAX_LEVEL out number -- Максимальный уровень иерархии
); );
/* Инициализация планов и отчетов производства изделий */ /* Инициализация каталогов раздела "Планы и отчеты производства изделий" */
procedure PRODPLAN_INIT procedure ACATALOG_INIT
( (
COUT out clob -- Список планов и отчетов производства изделий COUT out clob -- Список каталогов раздела "Планы и отчеты производства изделий"
); );
end PKG_P8PANELS_MECHREC; end PKG_P8PANELS_MECHREC;
@ -32,6 +33,9 @@ create or replace package body PKG_P8PANELS_MECHREC as
SFCPRODPLAN_TYPE constant PKG_STD.TSTRING := 'План'; -- Тип планов (мнемокод состояния) SFCPRODPLAN_TYPE constant PKG_STD.TSTRING := 'План'; -- Тип планов (мнемокод состояния)
/* Константы - дополнительные атрибуты */ /* Константы - дополнительные атрибуты */
STASK_ATTR_PROD_ORDER constant PKG_STD.TSTRING := 'prod_order'; -- Заказ
STASK_ATTR_SUBDIV_DLVR constant PKG_STD.TSTRING := 'subdiv_dlvr'; -- Сдающее подразделение
STASK_ATTR_MAIN_QUANT constant PKG_STD.TSTRING := 'main_quant'; -- Выпуск
STASK_ATTR_DEFRESLIZ constant PKG_STD.TSTRING := 'defresliz'; -- Дефицит запуска STASK_ATTR_DEFRESLIZ constant PKG_STD.TSTRING := 'defresliz'; -- Дефицит запуска
STASK_ATTR_REL_FACT constant PKG_STD.TSTRING := 'rel_fact'; -- Выпуск факт STASK_ATTR_REL_FACT constant PKG_STD.TSTRING := 'rel_fact'; -- Выпуск факт
STASK_ATTR_DEFSTART constant PKG_STD.TSTRING := 'defstart'; -- Дефицит выпуска STASK_ATTR_DEFSTART constant PKG_STD.TSTRING := 'defstart'; -- Дефицит выпуска
@ -51,10 +55,18 @@ create or replace package body PKG_P8PANELS_MECHREC as
begin begin
/* Если дефицит запуска <> 0 */ /* Если дефицит запуска <> 0 */
if (NDEFRESLIZ <> 0) then if (NDEFRESLIZ <> 0) then
/* Если дефицит выпуска = 0 */
if (NDEFSTART = 0) then
/* Полностью зеленый */
STASK_BG_COLOR := SBG_COLOR_GREEN;
STASK_BG_PROGRESS_COLOR := null;
NTASK_PROGRESS := null;
else
/* Полностью красный */ /* Полностью красный */
STASK_BG_COLOR := SBG_COLOR_RED; STASK_BG_COLOR := SBG_COLOR_RED;
STASK_BG_PROGRESS_COLOR := null; STASK_BG_PROGRESS_COLOR := null;
NTASK_PROGRESS := null; NTASK_PROGRESS := null;
end if;
else else
/* Если дефицит выпуска = 0 */ /* Если дефицит выпуска = 0 */
if (NDEFSTART = 0) then if (NDEFSTART = 0) then
@ -81,48 +93,10 @@ create or replace package body PKG_P8PANELS_MECHREC as
end if; end if;
end MAKE_GANT_ITEM; end MAKE_GANT_ITEM;
/* Считывание заголовка документа */ /* Считывание максимального уровня иерархии плана по каталогу */
function TITLE_GET
(
NRN in number -- Рег. номер плана и отчета производства изделий
) return varchar2 -- Заголовок для отображения
is
SRESULT PKG_STD.TSTRING; -- Заголовок для отображения
SDOC_INFO PKG_STD.TSTRING; -- Информация о документе
SJURPERSONS_CODE PKG_STD.TSTRING; -- Мнемокод принадлежности
SINS_DEPARTMENT_CODE PKG_STD.TSTRING; -- Мнемокод подразделения
begin
/* Считываем информацию из плана */
begin
select D.DOCCODE || ', ' || trim(T.PREFIX) || '/' || trim(T.NUMB) || ', от ' || TO_CHAR(T.DOCDATE, 'dd.mm.yyyy') DOC_INFO,
J.CODE,
SD.CODE
into SDOC_INFO,
SJURPERSONS_CODE,
SINS_DEPARTMENT_CODE
from FCPRODPLAN T,
DOCTYPES D,
JURPERSONS J,
INS_DEPARTMENT SD
where T.RN = NRN
and D.RN = T.DOCTYPE
and J.RN = T.JUR_PERS
and SD.RN = T.SUBDIV;
exception
when others then
return 'Нет информации.';
end;
/* Формируем заголовок */
SRESULT := 'План и отчет производства изделия "' || SDOC_INFO || '", принадлежность "' || SJURPERSONS_CODE ||
'", подразделение "' || SINS_DEPARTMENT_CODE || '"';
/* Возвращаем результат */
return SRESULT;
end TITLE_GET;
/* Считывание максимального уровня иерархии плана */
function PRODPLAN_MAX_LEVEL_GET function PRODPLAN_MAX_LEVEL_GET
( (
NPRODPLAN in number -- Рег. номер плана NCRN in number -- Рег. номер каталога планов
) return number -- Максимальный уровень иерархии ) return number -- Максимальный уровень иерархии
is is
NRESULT PKG_STD.TNUMBER; -- Максимальный уровень иерархии NRESULT PKG_STD.TNUMBER; -- Максимальный уровень иерархии
@ -133,8 +107,31 @@ create or replace package body PKG_P8PANELS_MECHREC as
into NRESULT into NRESULT
from (select T.RN, from (select T.RN,
T.UP_LEVEL T.UP_LEVEL
from FCPRODPLANSP T from FCPRODPLAN P,
where T.PRN = NPRODPLAN) TMP FCPRODPLANSP T,
FINSTATE FS
where P.CRN = NCRN
and P.CATEGORY = NFCPRODPLAN_CATEGORY
and P.STATUS = NFCPRODPLAN_STATUS
and FS.RN = P.TYPE
and FS.CODE = SFCPRODPLAN_TYPE
and exists (select /*+ INDEX(UP I_USERPRIV_JUR_PERS_ROLEID) */
null
from USERPRIV UP
where UP.JUR_PERS = P.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 = P.JUR_PERS
and UP.UNITCODE = 'CostProductPlans'
and UP.AUTHID = UTILIZER)
and T.PRN = P.RN) TMP
connect by prior TMP.RN = TMP.UP_LEVEL connect by prior TMP.RN = TMP.UP_LEVEL
start with TMP.UP_LEVEL is null; start with TMP.UP_LEVEL is null;
exception exception
@ -189,8 +186,9 @@ create or replace package body PKG_P8PANELS_MECHREC as
/* Получение списка спецификаций планов и отчетов производства изделий для диаграммы Ганта */ /* Получение списка спецификаций планов и отчетов производства изделий для диаграммы Ганта */
procedure FCPRODPLANSP_GET procedure FCPRODPLANSP_GET
( (
NFCPRODPLAN in number, -- Рег. номер родителя NCRN in number, -- Рег. номер каталога
NLEVEL in number := null, -- Уровень отбора NLEVEL in number := null, -- Уровень отбора
SSORT_FIELD in varchar2 := 'DREP_DATE_TO', -- Поле сортировки
COUT out clob, -- Список проектов COUT out clob, -- Список проектов
NMAX_LEVEL out number -- Максимальный уровень иерархии NMAX_LEVEL out number -- Максимальный уровень иерархии
) )
@ -205,13 +203,61 @@ create or replace package body PKG_P8PANELS_MECHREC as
NTASK_PROGRESS PKG_STD.TNUMBER; -- Прогресс выполнения задачи NTASK_PROGRESS PKG_STD.TNUMBER; -- Прогресс выполнения задачи
DDATE_FROM PKG_STD.TLDATE; -- Дата запуска спецификации DDATE_FROM PKG_STD.TLDATE; -- Дата запуска спецификации
DDATE_TO PKG_STD.TLDATE; -- Дата выпуска спецификации DDATE_TO PKG_STD.TLDATE; -- Дата выпуска спецификации
STASK_CAPTION PKG_STD.TSTRING; -- Описание задачи в Ганте
CSQL clob; -- Буфер для запроса
ICURSOR integer; -- Курсор для исполнения запроса
/* Значения спецификации */
NTASK_RN PKG_STD.TREF; -- Рег. номер спецификации
NTASK_PRN PKG_STD.TREF; -- Рег. номер родителя спецификации
STASK_PROD_ORDER PKG_STD.TSTRING; -- Заказ
DTASK_REP_DATE PKG_STD.TLDATE; -- Дата запуска
DTASK_REP_DATE_TO PKG_STD.TLDATE; -- Дата выпуска
DTASK_INCL_DATE PKG_STD.TLDATE; -- Дата включения в план
STASK_ROUTE PKG_STD.TSTRING; -- Маршрут
STASK_NOMEN_NAME PKG_STD.TSTRING; -- Наименование номенклатуры
NTASK_DEFRESLIZ number; -- Дефицит запуска
NTASK_REL_FACT number; -- Выпуск факт
NTASK_DEFSTART number; -- Дефицит выпуска
NTASK_MAIN_QUANT number; -- Выпуск
STASK_SUBDIV_DLVR PKG_STD.TSTRING; -- Сдающее подразделение
NTASK_HAVE_LINK PKG_STD.TNUMBER; -- Наличие ссылок (0 - нет, 1 - да)
NTASK_UP_LEVEL PKG_STD.TREF; -- Рег. номер родительской записи в иерархии
NTASK_LEVEL PKG_STD.TNUMBER; -- Уровень в иерархии
/* Объединение значений в строковое представление */
function MAKE_INFO
(
SPROD_ORDER in varchar2, -- Заказ
SNOMEN_NAME in varchar2, -- Наименование номенклатуры
SSUBDIV_DLVR in varchar2, -- Сдающее подразделение
NMAIN_QUANT in number -- Выпуск
) return varchar2 -- Описание задачи в Ганте
is
SRESULT PKG_STD.TSTRING; -- Описание задачи в Ганте
begin
/* Соединяем информацию */
SRESULT := STRCOMBINE(SPROD_ORDER, SNOMEN_NAME, ', ');
SRESULT := STRCOMBINE(SRESULT, SSUBDIV_DLVR, ', ');
SRESULT := STRCOMBINE(SRESULT, TO_CHAR(NMAIN_QUANT), ', ');
/* Возвращаем результат */
return SRESULT;
end MAKE_INFO;
/* Инициализация динамических атрибутов */
procedure TASK_ATTRS_INIT
(
RG in out PKG_P8PANELS_VISUAL.TGANTT -- Описание диаграммы Ганта
)
is
begin begin
/* Инициализируем диаграмму Ганта */
RG := PKG_P8PANELS_VISUAL.TGANTT_MAKE(STITLE => TITLE_GET(NRN => NFCPRODPLAN),
NZOOM => PKG_P8PANELS_VISUAL.NGANTT_ZOOM_DAY,
BREAD_ONLY_DATES => BREAD_ONLY_DATES,
BREAD_ONLY_PROGRESS => true);
/* Добавим динамические атрибуты к спецификациям */ /* Добавим динамические атрибуты к спецификациям */
PKG_P8PANELS_VISUAL.TGANTT_ADD_TASK_ATTR(RGANTT => RG, SNAME => STASK_ATTR_PROD_ORDER, SCAPTION => 'Заказ');
PKG_P8PANELS_VISUAL.TGANTT_ADD_TASK_ATTR(RGANTT => RG,
SNAME => STASK_ATTR_SUBDIV_DLVR,
SCAPTION => 'Сдающее подразделение');
PKG_P8PANELS_VISUAL.TGANTT_ADD_TASK_ATTR(RGANTT => RG,
SNAME => STASK_ATTR_MAIN_QUANT,
SCAPTION => 'Выпуск');
PKG_P8PANELS_VISUAL.TGANTT_ADD_TASK_ATTR(RGANTT => RG, PKG_P8PANELS_VISUAL.TGANTT_ADD_TASK_ATTR(RGANTT => RG,
SNAME => STASK_ATTR_DEFRESLIZ, SNAME => STASK_ATTR_DEFRESLIZ,
SCAPTION => 'Дефицит запуска'); SCAPTION => 'Дефицит запуска');
@ -222,6 +268,15 @@ create or replace package body PKG_P8PANELS_MECHREC as
SNAME => STASK_ATTR_DEFSTART, SNAME => STASK_ATTR_DEFSTART,
SCAPTION => 'Дефицит выпуска'); SCAPTION => 'Дефицит выпуска');
PKG_P8PANELS_VISUAL.TGANTT_ADD_TASK_ATTR(RGANTT => RG, SNAME => STASK_ATTR_LEVEL, SCAPTION => 'Уровень'); PKG_P8PANELS_VISUAL.TGANTT_ADD_TASK_ATTR(RGANTT => RG, SNAME => STASK_ATTR_LEVEL, SCAPTION => 'Уровень');
end TASK_ATTRS_INIT;
/* Инициализация цветов */
procedure TASK_COLORS_INIT
(
RG in out PKG_P8PANELS_VISUAL.TGANTT -- Описание диаграммы Ганта
)
is
begin
/* Добавим описание цветов */ /* Добавим описание цветов */
PKG_P8PANELS_VISUAL.TGANTT_ADD_TASK_COLOR(RGANTT => RG, PKG_P8PANELS_VISUAL.TGANTT_ADD_TASK_COLOR(RGANTT => RG,
SBG_COLOR => SBG_COLOR_RED, SBG_COLOR => SBG_COLOR_RED,
@ -240,46 +295,192 @@ create or replace package body PKG_P8PANELS_MECHREC as
SBG_COLOR => SBG_COLOR_BLACK, SBG_COLOR => SBG_COLOR_BLACK,
STEXT_COLOR => STEXT_COLOR_ORANGE, STEXT_COLOR => STEXT_COLOR_ORANGE,
SDESC => 'Для спецификаций планов и отчетов производства изделий с пустыми «Дата запуска» и «Дата выпуска» и не имеющих связей с разделами «Маршрутный лист» или «Приход из подразделения».'); SDESC => 'Для спецификаций планов и отчетов производства изделий с пустыми «Дата запуска» и «Дата выпуска» и не имеющих связей с разделами «Маршрутный лист» или «Приход из подразделения».');
end TASK_COLORS_INIT;
/* Заполнение значений динамических атрибутов */
procedure FILL_TASK_ATTRS
(
RG in PKG_P8PANELS_VISUAL.TGANTT, -- Описание диаграммы Ганта
RGT in out nocopy PKG_P8PANELS_VISUAL.TGANTT_TASK, -- Описание задачи для диаграммы
SPROD_ORDER in varchar2, -- Заказ
SSUBDIV_DLVR in varchar2, -- Сдающее подразделение
NMAIN_QUANT in number, -- Выпуск
NDEFRESLIZ in number, -- Дефицит запуска
NREL_FACT in number, -- Выпуск факт
NDEFSTART in number, -- Дефицит выпуска
NLEVEL in number -- Уровень
)
is
begin
/* Добавим доп. атрибуты */
PKG_P8PANELS_VISUAL.TGANTT_TASK_ADD_ATTR_VAL(RGANTT => RG,
RTASK => RGT,
SNAME => STASK_ATTR_PROD_ORDER,
SVALUE => SPROD_ORDER,
BCLEAR => true);
PKG_P8PANELS_VISUAL.TGANTT_TASK_ADD_ATTR_VAL(RGANTT => RG,
RTASK => RGT,
SNAME => STASK_ATTR_SUBDIV_DLVR,
SVALUE => SSUBDIV_DLVR);
PKG_P8PANELS_VISUAL.TGANTT_TASK_ADD_ATTR_VAL(RGANTT => RG,
RTASK => RGT,
SNAME => STASK_ATTR_MAIN_QUANT,
SVALUE => TO_CHAR(NMAIN_QUANT));
PKG_P8PANELS_VISUAL.TGANTT_TASK_ADD_ATTR_VAL(RGANTT => RG,
RTASK => RGT,
SNAME => STASK_ATTR_DEFRESLIZ,
SVALUE => TO_CHAR(NDEFRESLIZ));
PKG_P8PANELS_VISUAL.TGANTT_TASK_ADD_ATTR_VAL(RGANTT => RG,
RTASK => RGT,
SNAME => STASK_ATTR_REL_FACT,
SVALUE => TO_CHAR(NREL_FACT));
PKG_P8PANELS_VISUAL.TGANTT_TASK_ADD_ATTR_VAL(RGANTT => RG,
RTASK => RGT,
SNAME => STASK_ATTR_DEFSTART,
SVALUE => TO_CHAR(NDEFSTART));
PKG_P8PANELS_VISUAL.TGANTT_TASK_ADD_ATTR_VAL(RGANTT => RG,
RTASK => RGT,
SNAME => STASK_ATTR_LEVEL,
SVALUE => TO_CHAR(NLEVEL));
end FILL_TASK_ATTRS;
begin
/* Инициализируем диаграмму Ганта */
RG := PKG_P8PANELS_VISUAL.TGANTT_MAKE(STITLE => 'Производственная программа',
NZOOM => PKG_P8PANELS_VISUAL.NGANTT_ZOOM_DAY,
BREAD_ONLY_DATES => BREAD_ONLY_DATES,
BREAD_ONLY_PROGRESS => true);
/* Инициализируем динамические атрибуты к спецификациям */
TASK_ATTRS_INIT(RG => RG);
/* Инициализируем описания цветов */
TASK_COLORS_INIT(RG => RG);
/* Определяем максимальный уровень иерархии */ /* Определяем максимальный уровень иерархии */
NMAX_LEVEL := PRODPLAN_MAX_LEVEL_GET(NPRODPLAN => NFCPRODPLAN); NMAX_LEVEL := PRODPLAN_MAX_LEVEL_GET(NCRN => NCRN);
/* Цикл по спецификации плана с учетом иерархии */ /* Обходим данные */
for REC in (select TMP.*, begin
level CSQL := 'select TMP.*,
from (select T.RN, level NTASK_LEVEL
T.REP_DATE, from (select T.RN NRN,
T.REP_DATE_TO, T.PRN NPRN,
T.INCL_DATE, (select PORD.NUMB from FACEACC PORD where PORD.RN = T.PROD_ORDER) SPROD_ORDER,
T.ROUTE, T.REP_DATE DREP_DATE,
D.NOMEN_NAME, T.REP_DATE_TO DREP_DATE_TO,
(T.QUANT_REST - T.START_FACT) DEFRESLIZ, T.INCL_DATE DINCL_DATE,
T.REL_FACT, T.ROUTE SROUTE,
(T.MAIN_QUANT - T.REL_FACT) DEFSTART, D.NOMEN_NAME SNOMEN_NAME,
(T.QUANT_REST - T.START_FACT) NDEFRESLIZ,
T.REL_FACT NREL_FACT,
(T.MAIN_QUANT - T.REL_FACT) NDEFSTART,
T.MAIN_QUANT NMAIN_QUANT,
(select IDD.CODE from INS_DEPARTMENT IDD where IDD.RN = T.SUBDIV_DLVR) SSUBDIV_DLVR,
(select 1 (select 1
from DUAL from DUAL
where exists where exists
(select null (select null
from DOCLINKS L from DOCLINKS L
where L.IN_DOCUMENT = T.RN where L.IN_DOCUMENT = T.RN
and L.IN_UNITCODE = 'CostProductPlansSpecs' and L.IN_UNITCODE = ''CostProductPlansSpecs''
and (L.OUT_UNITCODE = 'CostRouteLists' or L.OUT_UNITCODE = 'IncomFromDeps') and (L.OUT_UNITCODE = ''CostRouteLists'' or L.OUT_UNITCODE = ''IncomFromDeps'')
and ROWNUM = 1)) HAVE_LINK, and ROWNUM = 1)) NHAVE_LINK,
T.UP_LEVEL T.UP_LEVEL NUP_LEVEL
from FCPRODPLANSP T, from FCPRODPLAN P,
FINSTATE FS,
FCPRODPLANSP T,
FCMATRESOURCE FM, FCMATRESOURCE FM,
DICNOMNS D DICNOMNS D
where T.PRN = NFCPRODPLAN where P.CRN = :NCRN
and P.CATEGORY = :NFCPRODPLAN_CATEGORY
and P.STATUS = :NFCPRODPLAN_STATUS
and FS.RN = P.TYPE
and FS.CODE = :SFCPRODPLAN_TYPE
and exists
(select /*+ INDEX(UP I_USERPRIV_JUR_PERS_ROLEID) */
null
from USERPRIV UP
where UP.JUR_PERS = P.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 = P.JUR_PERS
and UP.UNITCODE = ''CostProductPlans''
and UP.AUTHID = UTILIZER)
and T.PRN = P.RN
and ((T.REP_DATE is not null) or (T.REP_DATE_TO is not null) or (T.INCL_DATE is not null)) and ((T.REP_DATE is not null) or (T.REP_DATE_TO is not null) or (T.INCL_DATE is not null))
and FM.RN = T.MATRES and FM.RN = T.MATRES
and D.RN = FM.NOMENCLATURE) TMP and D.RN = FM.NOMENCLATURE) TMP
where ((NLEVEL is null) or ((NLEVEL is not null) and (level <= NLEVEL))) where ((:NLEVEL is null) or ((:NLEVEL is not null) and (level <= :NLEVEL)))
connect by prior TMP.RN = TMP.UP_LEVEL connect by prior TMP.NRN = TMP.NUP_LEVEL
start with TMP.UP_LEVEL is null) start with TMP.NUP_LEVEL is null
order siblings by TMP.%SORT_FIELD% asc';
/* Подставляем поле сортировки */
CSQL := replace(CSQL, '%SORT_FIELD%', SSORT_FIELD);
/* Разбираем его */
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 => 'NCRN', NVALUE => NCRN);
PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR,
SNAME => 'NFCPRODPLAN_CATEGORY',
NVALUE => NFCPRODPLAN_CATEGORY);
PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NFCPRODPLAN_STATUS', NVALUE => NFCPRODPLAN_STATUS);
PKG_SQL_DML.BIND_VARIABLE_STR(ICURSOR => ICURSOR, SNAME => 'SFCPRODPLAN_TYPE', SVALUE => SFCPRODPLAN_TYPE);
PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NLEVEL', NVALUE => NLEVEL);
/* Описываем структуру записи курсора */
PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 1);
PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 2);
PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 3);
PKG_SQL_DML.DEFINE_COLUMN_DATE(ICURSOR => ICURSOR, IPOSITION => 4);
PKG_SQL_DML.DEFINE_COLUMN_DATE(ICURSOR => ICURSOR, IPOSITION => 5);
PKG_SQL_DML.DEFINE_COLUMN_DATE(ICURSOR => ICURSOR, IPOSITION => 6);
PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 7);
PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 8);
PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 9);
PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 10);
PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 11);
PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 12);
PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 13);
PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 14);
PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 15);
PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 16);
/* Делаем выборку */
if (PKG_SQL_DML.EXECUTE(ICURSOR => ICURSOR) = 0) then
null;
end if;
/* Обходим выбранные записи */
while (PKG_SQL_DML.FETCH_ROWS(ICURSOR => ICURSOR) > 0)
loop loop
/* Читаем данные из курсора */
PKG_SQL_DML.COLUMN_VALUE_NUM(ICURSOR => ICURSOR, IPOSITION => 1, NVALUE => NTASK_RN);
PKG_SQL_DML.COLUMN_VALUE_NUM(ICURSOR => ICURSOR, IPOSITION => 2, NVALUE => NTASK_PRN);
PKG_SQL_DML.COLUMN_VALUE_STR(ICURSOR => ICURSOR, IPOSITION => 3, SVALUE => STASK_PROD_ORDER);
PKG_SQL_DML.COLUMN_VALUE_DATE(ICURSOR => ICURSOR, IPOSITION => 4, DVALUE => DTASK_REP_DATE);
PKG_SQL_DML.COLUMN_VALUE_DATE(ICURSOR => ICURSOR, IPOSITION => 5, DVALUE => DTASK_REP_DATE_TO);
PKG_SQL_DML.COLUMN_VALUE_DATE(ICURSOR => ICURSOR, IPOSITION => 6, DVALUE => DTASK_INCL_DATE);
PKG_SQL_DML.COLUMN_VALUE_STR(ICURSOR => ICURSOR, IPOSITION => 7, SVALUE => STASK_ROUTE);
PKG_SQL_DML.COLUMN_VALUE_STR(ICURSOR => ICURSOR, IPOSITION => 8, SVALUE => STASK_NOMEN_NAME);
PKG_SQL_DML.COLUMN_VALUE_NUM(ICURSOR => ICURSOR, IPOSITION => 9, NVALUE => NTASK_DEFRESLIZ);
PKG_SQL_DML.COLUMN_VALUE_NUM(ICURSOR => ICURSOR, IPOSITION => 10, NVALUE => NTASK_REL_FACT);
PKG_SQL_DML.COLUMN_VALUE_NUM(ICURSOR => ICURSOR, IPOSITION => 11, NVALUE => NTASK_DEFSTART);
PKG_SQL_DML.COLUMN_VALUE_NUM(ICURSOR => ICURSOR, IPOSITION => 12, NVALUE => NTASK_MAIN_QUANT);
PKG_SQL_DML.COLUMN_VALUE_STR(ICURSOR => ICURSOR, IPOSITION => 13, SVALUE => STASK_SUBDIV_DLVR);
PKG_SQL_DML.COLUMN_VALUE_NUM(ICURSOR => ICURSOR, IPOSITION => 14, NVALUE => NTASK_HAVE_LINK);
PKG_SQL_DML.COLUMN_VALUE_NUM(ICURSOR => ICURSOR, IPOSITION => 15, NVALUE => NTASK_UP_LEVEL);
PKG_SQL_DML.COLUMN_VALUE_NUM(ICURSOR => ICURSOR, IPOSITION => 16, NVALUE => NTASK_LEVEL);
/* Формируем описание задачи в Ганте */
STASK_CAPTION := MAKE_INFO(SPROD_ORDER => STASK_PROD_ORDER,
SNOMEN_NAME => STASK_NOMEN_NAME,
SSUBDIV_DLVR => STASK_SUBDIV_DLVR,
NMAIN_QUANT => NTASK_MAIN_QUANT);
/* Инициализируем даты и цвет (если необходимо) */ /* Инициализируем даты и цвет (если необходимо) */
FCPRODPLANSP_DATES_GET(DREP_DATE => REC.REP_DATE, FCPRODPLANSP_DATES_GET(DREP_DATE => DTASK_REP_DATE,
DREP_DATE_TO => REC.REP_DATE_TO, DREP_DATE_TO => DTASK_REP_DATE_TO,
DINCL_DATE => REC.INCL_DATE, DINCL_DATE => DTASK_INCL_DATE,
NHAVE_LINK => COALESCE(REC.HAVE_LINK, 0), NHAVE_LINK => COALESCE(NTASK_HAVE_LINK, 0),
DDATE_FROM => DDATE_FROM, DDATE_FROM => DDATE_FROM,
DDATE_TO => DDATE_TO, DDATE_TO => DDATE_TO,
STASK_BG_COLOR => STASK_BG_COLOR, STASK_BG_COLOR => STASK_BG_COLOR,
@ -288,18 +489,18 @@ create or replace package body PKG_P8PANELS_MECHREC as
/* Если цвет изначально не указан и требуется анализирование */ /* Если цвет изначально не указан и требуется анализирование */
if (STASK_BG_COLOR is null) then if (STASK_BG_COLOR is null) then
/* Формирование характеристик элемента ганта */ /* Формирование характеристик элемента ганта */
MAKE_GANT_ITEM(NDEFRESLIZ => REC.DEFRESLIZ, MAKE_GANT_ITEM(NDEFRESLIZ => NTASK_DEFRESLIZ,
NREL_FACT => REC.REL_FACT, NREL_FACT => NTASK_REL_FACT,
NDEFSTART => REC.DEFSTART, NDEFSTART => NTASK_DEFSTART,
STASK_BG_COLOR => STASK_BG_COLOR, STASK_BG_COLOR => STASK_BG_COLOR,
STASK_BG_PROGRESS_COLOR => STASK_BG_PROGRESS_COLOR, STASK_BG_PROGRESS_COLOR => STASK_BG_PROGRESS_COLOR,
NTASK_PROGRESS => NTASK_PROGRESS); NTASK_PROGRESS => NTASK_PROGRESS);
end if; end if;
/* Сформируем основную спецификацию */ /* Сформируем основную спецификацию */
RGT := PKG_P8PANELS_VISUAL.TGANTT_TASK_MAKE(NRN => REC.RN, RGT := PKG_P8PANELS_VISUAL.TGANTT_TASK_MAKE(NRN => NTASK_RN,
SNUMB => COALESCE(REC.ROUTE, 'Отсутствует'), SNUMB => COALESCE(STASK_ROUTE, 'Отсутствует'),
SCAPTION => REC.NOMEN_NAME, SCAPTION => STASK_CAPTION,
SNAME => REC.NOMEN_NAME, SNAME => STASK_NOMEN_NAME,
DSTART => DDATE_FROM, DSTART => DDATE_FROM,
DEND => DDATE_TO, DEND => DDATE_TO,
NPROGRESS => NTASK_PROGRESS, NPROGRESS => NTASK_PROGRESS,
@ -309,30 +510,22 @@ create or replace package body PKG_P8PANELS_MECHREC as
BREAD_ONLY => true, BREAD_ONLY => true,
BREAD_ONLY_DATES => true, BREAD_ONLY_DATES => true,
BREAD_ONLY_PROGRESS => true); BREAD_ONLY_PROGRESS => true);
/* Добавим доп. атрибуты */ /* Заполним значение динамических атрибутов */
PKG_P8PANELS_VISUAL.TGANTT_TASK_ADD_ATTR_VAL(RGANTT => RG, FILL_TASK_ATTRS(RG => RG,
RTASK => RGT, RGT => RGT,
SNAME => STASK_ATTR_DEFRESLIZ, SPROD_ORDER => STASK_PROD_ORDER,
SVALUE => TO_CHAR(REC.DEFRESLIZ), SSUBDIV_DLVR => STASK_SUBDIV_DLVR,
BCLEAR => true); NMAIN_QUANT => NTASK_MAIN_QUANT,
PKG_P8PANELS_VISUAL.TGANTT_TASK_ADD_ATTR_VAL(RGANTT => RG, NDEFRESLIZ => NTASK_DEFRESLIZ,
RTASK => RGT, NREL_FACT => NTASK_REL_FACT,
SNAME => STASK_ATTR_REL_FACT, NDEFSTART => NTASK_DEFSTART,
SVALUE => TO_CHAR(REC.REL_FACT)); NLEVEL => NTASK_LEVEL);
PKG_P8PANELS_VISUAL.TGANTT_TASK_ADD_ATTR_VAL(RGANTT => RG,
RTASK => RGT,
SNAME => STASK_ATTR_DEFSTART,
SVALUE => TO_CHAR(REC.DEFSTART));
PKG_P8PANELS_VISUAL.TGANTT_TASK_ADD_ATTR_VAL(RGANTT => RG,
RTASK => RGT,
SNAME => STASK_ATTR_LEVEL,
SVALUE => REC.LEVEL);
/* Собираем зависимости */ /* Собираем зависимости */
for LINK in (select T.RN for LINK in (select T.RN
from FCPRODPLANSP T from FCPRODPLANSP T
where T.PRN = NFCPRODPLAN where T.PRN = NTASK_PRN
and T.UP_LEVEL = REC.RN and T.UP_LEVEL = NTASK_RN
and ((NLEVEL is null) or ((NLEVEL is not null) and (NLEVEL >= REC.LEVEL + 1)))) and ((NLEVEL is null) or ((NLEVEL is not null) and (NLEVEL >= NTASK_LEVEL + 1))))
loop loop
/* Добавляем зависимости */ /* Добавляем зависимости */
PKG_P8PANELS_VISUAL.TGANTT_TASK_ADD_DEPENDENCY(RTASK => RGT, NDEPENDENCY => LINK.RN); PKG_P8PANELS_VISUAL.TGANTT_TASK_ADD_DEPENDENCY(RTASK => RGT, NDEPENDENCY => LINK.RN);
@ -340,14 +533,21 @@ create or replace package body PKG_P8PANELS_MECHREC as
/* Добавляем основную спецификацию в диаграмму */ /* Добавляем основную спецификацию в диаграмму */
PKG_P8PANELS_VISUAL.TGANTT_ADD_TASK(RGANTT => RG, RTASK => RGT); PKG_P8PANELS_VISUAL.TGANTT_ADD_TASK(RGANTT => RG, RTASK => RGT);
end loop; 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.TGANTT_TO_XML(RGANTT => RG); COUT := PKG_P8PANELS_VISUAL.TGANTT_TO_XML(RGANTT => RG);
end FCPRODPLANSP_GET; end FCPRODPLANSP_GET;
/* Инициализация планов и отчетов производства изделий */ /* Инициализация каталогов раздела "Планы и отчеты производства изделий" */
procedure PRODPLAN_INIT procedure ACATALOG_INIT
( (
COUT out clob -- Список планов и отчетов производства изделий COUT out clob -- Список каталогов раздела "Планы и отчеты производства изделий"
) )
is is
begin begin
@ -356,54 +556,27 @@ create or replace package body PKG_P8PANELS_MECHREC as
/* Открываем корень */ /* Открываем корень */
PKG_XFAST.DOWN_NODE(SNAME => 'XDATA'); PKG_XFAST.DOWN_NODE(SNAME => 'XDATA');
/* Цикл по планам и отчетам производства изделий */ /* Цикл по планам и отчетам производства изделий */
for REC in (select T.RN NRN, for REC in (select T.RN as NRN,
D.DOCCODE || ', ' || trim(T.PREFIX) || '/' || trim(T.NUMB) || ', ' || T.NAME as SNAME
TO_CHAR(T.DOCDATE, 'dd.mm.yyyy') SDOC_INFO from ACATALOG T,
from FCPRODPLAN T, UNITLIST UL
DOCTYPES D, where T.DOCNAME = 'CostProductPlans'
FINSTATE FS and T.SIGNS = 1
where T.CATEGORY = NFCPRODPLAN_CATEGORY and T.DOCNAME = UL.UNITCODE
and T.STATUS = NFCPRODPLAN_STATUS and (UL.SHOW_INACCESS_CTLG = 1 or exists
and D.RN = T.DOCTYPE (select null from V_USERPRIV UP where UP.CATALOG = T.RN) or exists
and FS.RN = T.TYPE (select null
and FS.CODE = SFCPRODPLAN_TYPE from ACATALOG T1
and exists (select /*+ INDEX(UP I_USERPRIV_CATALOG_ROLEID) */ where exists (select null from V_USERPRIV UP where UP.CATALOG = T1.RN)
null connect by prior T1.RN = T1.CRN
from USERPRIV UP start with T1.CRN = T.RN))
where UP.CATALOG = T.CRN order by T.NAME asc)
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)
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)
order by T.DOCDATE desc)
loop loop
/* Открываем план */ /* Открываем план */
PKG_XFAST.DOWN_NODE(SNAME => 'XFCPRODPLANS'); 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 => 'SDOC_INFO', SVALUE => REC.SDOC_INFO); PKG_XFAST.ATTR(SNAME => 'SNAME', SVALUE => REC.SNAME);
/* Закрываем план */ /* Закрываем план */
PKG_XFAST.UP(); PKG_XFAST.UP();
end loop; end loop;
@ -420,7 +593,7 @@ create or replace package body PKG_P8PANELS_MECHREC as
/* Вернем ошибку */ /* Вернем ошибку */
PKG_STATE.DIAGNOSTICS_STACKED(); PKG_STATE.DIAGNOSTICS_STACKED();
P_EXCEPTION(0, PKG_STATE.SQL_ERRM()); P_EXCEPTION(0, PKG_STATE.SQL_ERRM());
end PRODPLAN_INIT; end ACATALOG_INIT;
end PKG_P8PANELS_MECHREC; end PKG_P8PANELS_MECHREC;
/ /