ЦИТК-791 + ЦИТК-834 - Панель "Выполнение работ" по ТОиР - детализация ячеек и косметика

This commit is contained in:
Mikhail Chechnev 2024-04-18 08:31:32 +03:00 committed by GitHub
commit f31030cbc5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 702 additions and 403 deletions

View File

@ -32,7 +32,9 @@ import { P8PDataGrid, P8P_DATA_GRID_SIZE } from "../../components/p8p_data_grid"
import { P8P_DATA_GRID_CONFIG_PROPS } from "../../config_wrapper"; //Подключение компонентов к настройкам приложения
import { BackEndСtx } from "../../context/backend"; //Контекст взаимодействия с сервером
import { ApplicationСtx } from "../../context/application"; //Контекст приложения
import { MessagingСtx } from "../../context/messaging"; //Контекст сообщений
import { headCellRender, dataCellRender, groupCellRender, DIGITS_REG_EXP, MONTH_NAME_REG_EXP, DAY_NAME_REG_EXP } from "./layouts"; //Дополнительная разметка и вёрстка клиентских элементов
import { TEXTS } from "../../../app.text"; //Тектовые ресурсы и константы
//-----------
//Тело модуля
@ -49,74 +51,55 @@ const EqsPrfrm = () => {
reload: false
});
const [filter, setFilter] = useState({
belong: "Демопример",
prodObj: "К2",
techServ: "",
respDep: "",
fromMonth: 1,
fromYear: 2024,
toMonth: 12,
toYear: 2024
});
// const [filter, setFilter] = useState({
// belong: "",
// prodObj: "",
// techServ: "",
// respDep: "",
// fromMonth: "",
// fromYear: "",
// toMonth: "",
// toYear: ""});
// Состояние информации о трудоёмкости
const [info, setInfo] = useState({ cntP: 0, sumP: 0, cntF: 0, sumF: 0 });
//Подключение к контексту приложения
const { pOnlineShowDictionary } = useContext(ApplicationСtx);
// Состояние фильтра (для отладки)
// const [filter, setFilter] = useState({
// belong: "Демопример",
// prodObj: "Карьер",
// techServ: "",
// respDep: "",
// fromMonth: 1,
// fromYear: 2024,
// toMonth: 12,
// toYear: 2024
// });
const [filterOpen, setFilterOpen] = useState(false);
const [filterCopy, setFilterCopy] = useState({ ...filter });
const [filterLock, setFilterLock] = useState(false);
const openFilter = () => {
setFilterOpen(true);
};
const closeFilter = e => {
if (filterLock && e != undefined) setFilter(filterCopy);
setFilterOpen(false);
};
const clearFilter = () => {
setFilter({
// Состояние фильтра
const [filter, setFilter] = useState({
belong: "",
prodObj: "",
techServ: "",
respDep: "",
fromMonth: "",
fromYear: "",
toMonth: "",
toYear: ""
fromMonth: 1,
fromYear: 1990,
toMonth: 1,
toYear: 1990
});
};
// Состояние открытия фильтра
const [filterOpen, setFilterOpen] = useState(true);
// Состояние данных по умолчанию для фильтра (true - для отладки)
const [defaultLoaded, setDefaultLoaded] = useState(false);
// Состояние хранения копии фильтра
const [filterCopy, setFilterCopy] = useState({ ...filter });
// Состояние ограничения редактирования фильтра
const [filterLock, setFilterLock] = useState(false);
let yearArray = [];
let today = new Date();
// Состояние ячейки заголовка даты (по раскрытию/скрытию)
const [activeRef, setActiveRef] = useState();
// Состояние актуальности ссылки на ячейку
const [refIsDeprecated, setRidFlag] = useState(true);
const getYearArray = () => {
for (let i = 1990; i <= today.getFullYear(); i++) {
yearArray.push(i);
}
};
const monthArray = ["Январь", "Февраль", "Март", "Апрель", "Май", "Июнь", "Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь"];
//Подключение к контексту приложения
const { pOnlineShowDictionary, pOnlineShowUnit } = useContext(ApplicationСtx);
//Подключение к контексту взаимодействия с сервером
const { executeStored } = useContext(BackEndСtx);
//Подключение к контексту сообщений
const { showMsgErr } = useContext(MessagingСtx);
//Загрузка данных таблицы с сервера
const loadData = useCallback(async () => {
if (dataGrid.reload) {
@ -144,12 +127,15 @@ const EqsPrfrm = () => {
data.XROWS.map(row => {
properties = [];
Object.entries(row).forEach(([key, value]) => properties.push({ name: key, data: value }));
if (properties[1].data == "Факт" || properties[2].data == "План") {
if (properties[2].data == "План") {
let info2 = properties.find(element => {
return element.name === "SINFO2";
});
if (info2 != undefined) {
if (info2.data == "План") {
properties.map(p => {
if (DAY_NAME_REG_EXP.test(p.name)) cP = cP + 1;
});
} else if (properties[1].data == "Факт") {
} else if (info2.data == "Факт") {
properties.map(p => {
if (DAY_NAME_REG_EXP.test(p.name)) cF = cF + 1;
});
@ -184,27 +170,134 @@ const EqsPrfrm = () => {
}
}, [dataGrid.reload, filter, executeStored]);
//пользовательский параметр JuridicalPerson системы
const getJurPers = useCallback(async () => {
//Загрузка значений фильра по умолчанию
const loadDefaultFilter = useCallback(async () => {
const data = await executeStored({
stored: "PKG_P8PANELS_EQUIPSRV.GET_JUR_PERS_PRM",
respArg: "CRES"
stored: "PKG_P8PANELS_EQUIPSRV.GET_DEFAULT_FP",
respArg: "COUT"
});
setFilter(pv => ({ ...pv, belong: data }));
setFilter(pv => ({ ...pv, belong: data.JURPERS, fromMonth: data.MONTH, fromYear: data.YEAR, toMonth: data.MONTH, toYear: data.YEAR }));
setDefaultLoaded(true);
}, [executeStored]);
useEffect(() => {
if (filterOpen) {
setFilterCopy({ ...filter });
//пользовательский параметр JuridicalPerson системы
// const getJurPers = useCallback(async () => {
// const data = await executeStored({
// stored: "PKG_P8PANELS_EQUIPSRV.GET_JUR_PERS_PRM",
// respArg: "CRES"
// });
// setFilter(pv => ({ ...pv, belong: data }));
// }, [executeStored]);
// Отбор документа (ТОиР или Ремонтных ведомостей) по ячейке даты
const showEquipSrv = async ({ date, workType, info }) => {
const [techName, servKind] = info.split("_");
let type;
if (workType == "План") type = 0;
else type = 1;
let [year, month, day] = date.substring(1).split("_");
//if (day == undefined) day = null;
const data = await executeStored({
stored: "PKG_P8PANELS_EQUIPSRV.SELECT_EQUIPSRV",
args: {
SBELONG: filter.belong,
SPRODOBJ: filter.prodObj,
STECHSERV: filter.techServ ? filter.techServ : null,
SRESPDEP: filter.respDep ? filter.respDep : null,
STECHNAME: techName,
SSRVKIND: servKind,
NYEAR: Number(year),
NMONTH: Number(month),
NDAY: day ? Number(day) : null,
NWORKTYPE: type
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [filterOpen]);
});
if (data.NIDENT) {
if (type == 0) pOnlineShowUnit({ unitCode: "EquipTechServices", inputParameters: [{ name: "in_SelectList_Ident", value: data.NIDENT }] });
else pOnlineShowUnit({ unitCode: "EquipRepairSheets", inputParameters: [{ name: "in_Ident", value: data.NIDENT }] });
} else showMsgErr(TEXTS.NO_DATA_FOUND);
};
// Открыть фильтр
const openFilter = () => {
setFilterOpen(true);
};
// Закрыть фильтр
const closeFilter = e => {
if (filterLock && e != undefined) setFilter(filterCopy);
setFilterOpen(false);
};
// Очистить фильтр
const clearFilter = () => {
setFilter({
belong: "",
prodObj: "",
techServ: "",
respDep: "",
fromMonth: "",
fromYear: "",
toMonth: "",
toYear: ""
});
};
// Отработка события скрытия/раскрытия ячейки даты
const handleClick = (e, ref) => {
const curCell = ref.current;
if (e.target.type == "button" || e.target.offsetParent.type == "button") {
setActiveRef(curCell);
setRidFlag(false);
}
};
// При необходимости обновить данные таблицы
useEffect(() => {
loadData();
}, [loadData, dataGrid.reload]);
// При открытом фильтре
useEffect(() => {
if (filterOpen) {
{
setFilterCopy({ ...filter });
if (!defaultLoaded) loadDefaultFilter();
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [filterOpen]);
// При нажатии скрытии/раскрытии ячейки даты, фокус на неё
useEffect(() => {
if (!refIsDeprecated) {
if (activeRef) {
var cellRect = activeRef.getBoundingClientRect();
//console.log(window.scrollX + cellRect.left + activeRef.clientWidth / 2 - window.innerWidth / 2);
window.scrollTo(window.scrollX + cellRect.left + activeRef.clientWidth / 2 - window.innerWidth / 2, 0);
setRidFlag(true);
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [refIsDeprecated]);
let yearArray = [];
const monthArray = ["Январь", "Февраль", "Март", "Апрель", "Май", "Июнь", "Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь"];
let today = new Date();
// Получение списка лет
const getYearArray = () => {
for (let i = 1990; i <= today.getFullYear(); i++) {
yearArray.push(i);
}
};
//Генерация содержимого
return (
<div>
@ -254,26 +347,11 @@ const EqsPrfrm = () => {
aria-describedby="belong-outlined-helper-text"
label="Принадлежность"
/>
<Grid container>
<Grid item xs={6}>
{filter.belong ? null : (
<FormHelperText id="belong-outlined-helper-text" sx={{ color: "red" }}>
*Обязательное поле
</FormHelperText>
)}
</Grid>
<Grid item xs={6} sx={{ textAlign: "end" }}>
<Link
component="button"
variant="body2"
id="belong-outlined-link-btn"
sx={{ fontSize: "0.75rem", marginRight: "35px" }}
onClick={getJurPers}
>
Значение по умолчанию
</Link>
</Grid>
</Grid>
</FormControl>
</Box>
<Box component="section" sx={{ p: 1 }}>
@ -498,10 +576,10 @@ const EqsPrfrm = () => {
closeFilter();
}}
>
Сформировать отчёт
Сформировать
</Button>
<Button variant="contained" onClick={clearFilter}>
Очистить фильтр
Очистить
</Button>
<Button
variant="contained"
@ -509,7 +587,7 @@ const EqsPrfrm = () => {
setFilter(filterCopy);
}}
>
Отменить изменения
Отмена
</Button>
</DialogActions>
</Dialog>
@ -536,8 +614,10 @@ const EqsPrfrm = () => {
rows={dataGrid.rows}
size={P8P_DATA_GRID_SIZE.LARGE}
reloading={dataGrid.reload}
headCellRender={prms => headCellRender({ ...prms }, filter.techServ, info.cntP, info.sumP, info.cntF, info.sumF)}
dataCellRender={prms => dataCellRender({ ...prms })}
headCellRender={prms =>
headCellRender({ ...prms }, handleClick, filter.techServ, info.cntP, info.sumP, info.cntF, info.sumF)
}
dataCellRender={prms => dataCellRender({ ...prms }, showEquipSrv)}
groupCellRender={prms => groupCellRender({ ...prms })}
showCellRightBorder={true}
/>

View File

@ -7,8 +7,8 @@
//Подключение библиотек
//---------------------
import React, { createRef } from "react"; //Классы React
import { Grid, Stack } from "@mui/material";
import React from "react"; //Классы React
//---------
//Константы
@ -25,6 +25,7 @@ let x = 0;
//-----------
//Тело модуля
//-----------
const formatDate = date => {
const [year, month, day] = date.substring(1).split("_");
let nd;
@ -33,76 +34,96 @@ const formatDate = date => {
return nd;
};
export const headCellRender = ({ columnDef }, podr, cntP, sumP, cntF, sumF) => {
// eslint-disable-next-line no-unused-vars
export const headCellRender = ({ columnDef }, hClick, podr, cntP, sumP, cntF, sumF) => {
let cellStyle = { border: "1px solid rgba(0, 0, 0)", textAlign: "center" };
let cellProps = {};
let stackStyle = {};
let data = columnDef.caption;
if (columnDef.expandable) {
// поменять расположение + для развёртывания
const ref = createRef();
cellStyle = { ...cellStyle, padding: "5px" };
cellProps = {
...cellProps,
ref: ref,
onClick: e => {
hClick(e, ref);
}
};
stackStyle = { flexDirection: "column" };
}
if (columnDef.name == "STEST") cellStyle = { display: "none" };
if (columnDef.name == "SINFO" || columnDef.name == "SINFO2") {
cellProps = { colSpan: 2 };
if (columnDef.name == "SINFO") {
cellStyle = { ...cellStyle, padding: "unset" };
data = (
<Stack sx={{ justifyContent: "center" }} direction="row" width={300}>
<Grid container>
<Grid item xs={4}>
Подразделение:
</Grid>
<Grid item xs={8}>
{podr}
</Grid>
<Grid item xs={4}>
Кол-во ремонтов, план:
</Grid>
<Grid item xs={2}>
{cntP}
</Grid>
<Grid item xs={4}>
Трудоемкость, час. план:
</Grid>
<Grid item xs={2}>
{sumP}
</Grid>
<Grid item xs={4}>
Кол-во ремонтов, факт:
</Grid>
<Grid item xs={2}>
{cntF}
</Grid>
<Grid item xs={4}>
Трудоемкость, час. факт:
</Grid>
<Grid item xs={2}>
{sumF}
</Grid>
</Grid>
</Stack>
);
}
if (columnDef.name == "SINFO") cellProps = { ...cellProps, rowSpan: 2 };
//if (columnDef.name == "SINFO") {
//cellStyle = { display: "none" };
// cellStyle = { ...cellStyle, padding: "unset" };
// data = (
// <Stack sx={{ justifyContent: "center" }} direction="row" width={300}>
// <Grid container>
// <Grid item xs={4}>
// Подразделение:
// </Grid>
// <Grid item xs={8}>
// {podr}
// </Grid>
// <Grid item xs={4}>
// Кол-во ремонтов, план:
// </Grid>
// <Grid item xs={2}>
// {cntP}
// </Grid>
// <Grid item xs={4}>
// Трудоемкость, час. план:
// </Grid>
// <Grid item xs={2}>
// {sumP}
// </Grid>
// <Grid item xs={4}>
// Кол-во ремонтов, факт:
// </Grid>
// <Grid item xs={2}>
// {cntF}
// </Grid>
// <Grid item xs={4}>
// Трудоемкость, час. факт:
// </Grid>
// <Grid item xs={2}>
// {sumF}
// </Grid>
// </Grid>
// </Stack>
// );
//}
}
if (columnDef.name == "SINFO2") cellStyle = { display: "none" };
if (columnDef.visible && DAY_NAME_REG_EXP.test(columnDef.name)) {
cellStyle = { ...cellStyle, paddingLeft: "5px", paddingRight: "5px", minWidth: "25px", maxWidth: "25px" };
cellStyle = { ...cellStyle, padding: "5px", minWidth: "25px", maxWidth: "25px" };
stackStyle = { justifyContent: "center" };
}
return { cellStyle, cellProps, data };
return { cellStyle, cellProps, stackStyle, data };
};
export const dataCellRender = ({ row, columnDef }) => {
export const dataCellRender = ({ row, columnDef }, showEquipSrv) => {
let cellStyle = {
padding: "2px",
border: "1px solid rgba(0, 0, 0)",
border: "1px solid rgba(0, 0, 0) !important",
textAlign: "center"
};
let cellProps = {};
let data = " ";
if (row["SINFO2"] == undefined) {
if (columnDef.name == "STEST") cellProps = { colSpan: 2 };
if (columnDef.name == "STEST") {
cellProps = { colSpan: 2 };
cellStyle = { ...cellStyle, textAlign: "right", fontWeight: "bold" };
}
if (columnDef.name == "SINFO2") cellStyle = { display: "none" };
if (columnDef.parent == "" && columnDef.expandable == true && columnDef.expanded == false) {
curParent = columnDef.name;
@ -130,16 +151,31 @@ export const dataCellRender = ({ row, columnDef }) => {
switch (row[columnDef.name]) {
case "blue":
cellStyle = { ...cellStyle, backgroundColor: "royalblue", border: "1px solid rgba(0, 0, 0)" };
cellProps = { title: formatDate(columnDef.name) };
cellStyle = { ...cellStyle, backgroundColor: "lightblue", border: "1px solid rgba(0, 0, 0) !important" };
cellProps = {
title: formatDate(columnDef.name),
onClick: () => {
showEquipSrv({ date: columnDef.name, workType: row["SINFO2"], info: row["groupName"] });
}
};
return { cellStyle, cellProps, data };
case "green":
cellStyle = { ...cellStyle, backgroundColor: "lawngreen", border: "1px solid rgba(0, 0, 0)" };
cellProps = { title: formatDate(columnDef.name) };
cellStyle = { ...cellStyle, backgroundColor: "green", border: "1px solid rgba(0, 0, 0) !important" };
cellProps = {
title: formatDate(columnDef.name),
onClick: () => {
showEquipSrv({ date: columnDef.name, workType: row["SINFO2"], info: row["groupName"] });
}
};
return { cellStyle, cellProps, data };
case "red":
cellStyle = { ...cellStyle, backgroundColor: "crimson", border: "1px solid rgba(0, 0, 0)" };
cellProps = { title: formatDate(columnDef.name) };
cellStyle = { ...cellStyle, backgroundColor: "crimson", border: "1px solid rgba(0, 0, 0) !important" };
cellProps = {
title: formatDate(columnDef.name),
onClick: () => {
showEquipSrv({ date: columnDef.name, workType: row["SINFO2"], info: row["groupName"] });
}
};
return { cellStyle, cellProps, data };
case "green red":
case "red green":
@ -148,10 +184,20 @@ export const dataCellRender = ({ row, columnDef }) => {
data = (
<Stack sx={{ justifyContent: "center" }} direction="row">
<Grid container maxHeight="100%">
<Grid item xs={6} sx={{ backgroundColor: "lawngreen" }}>
<Grid
item
xs={6}
sx={{ backgroundColor: "green" }}
onClick={() => showEquipSrv({ date: columnDef.name, workType: row["SINFO2"], info: row["groupName"] })}
>
<p style={{ display: "none" }}>g</p>
</Grid>
<Grid item xs={6} sx={{ backgroundColor: "crimson" }}>
<Grid
item
xs={6}
sx={{ backgroundColor: "crimson" }}
onClick={() => showEquipSrv({ date: columnDef.name, workType: row["SINFO2"], info: row["groupName"] })}
>
<p style={{ display: "none" }}>r</p>
</Grid>
</Grid>

View File

@ -1,48 +1,80 @@
create or replace package PKG_P8PANELS_EQUIPSRV as
/* Получение значения системного параметра "JuridicalPerson" */
procedure GET_JUR_PERS_PRM
/* Получение параметров фильтра по умолчанию */
procedure GET_DEFAULT_FP
(
CRES out clob -- Значение параметра "JuridicalPerson" (null - если не нашли)
COUT out clob -- XML с параметрами фильтра по умолчанию
);
/* Формирование строки с кол-вом часов */
function HOURS_STR
(
NHOURS in number -- Кол-во часов
) return varchar2;
) return varchar2; -- Результат работы
/* Отбор документов (ТОиР или Графики ремонтов) по дате */
procedure SELECT_EQUIPSRV
(
SBELONG in varchar2, -- Принадлежность к Юр. лицу
SPRODOBJ in varchar2, -- Производственный объект
STECHSERV in varchar2 := null, -- Техническая служба
SRESPDEP in varchar2 := null, -- Ответственное подразделение
STECHNAME in varchar2, -- Наименование объекта ремонта
SSRVKIND in varchar2, -- Код вида ремонта
NYEAR in number, -- Год
NMONTH in number, -- Месяц
NDAY in number := null, -- День
NWORKTYPE in number, -- Тип работы (0 - план, 1 - факт)
NIDENT out number -- Идентификатор буфера подобранных (списка отмеченных записей, null - не найдено)
);
/* Выполнение работ по ТОиР */
procedure EQUIPSRV_GRID
(
SBELONG in varchar2, -- Принадлежность к Юр. лицу
SPRODOBJ in varchar2, -- Производственный объект
STECHSERV in varchar2, -- Техническая служба
SRESPDEP in varchar2, -- Ответственное подразделение
STECHSERV in varchar2 := null, -- Техническая служба
SRESPDEP in varchar2 := null, -- Ответственное подразделение
NFROMMONTH in number, -- Месяц начала периода
NFROMYEAR in number, -- Год начала периода
NTOMONTH in number, -- Месяц окончания периода
NTOYEAR in number, -- Год окончания периода
COUT out clob -- График проектов
);
end PKG_P8PANELS_EQUIPSRV;
/
create or replace package body PKG_P8PANELS_EQUIPSRV as
/* Получение значения системного параметра "JuridicalPerson" */
procedure GET_JUR_PERS_PRM
/* Получение параметров фильтра по умолчанию */
procedure GET_DEFAULT_FP
(
CRES out clob -- Значение параметра "JuridicalPerson" (null - если не нашли)
COUT out clob -- XML с параметрами фильтра по умолчанию
)
is
NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Рег. номер организации
SPARAMCODE PKG_STD.TSTRING := 'JuridicalPerson'; -- Код параметра
SJUR_PERS PKG_STD.TSTRING := null; -- Юр. лицо (наименование)
NJUR_PERS PKG_STD.TREF := null; -- Юр. лицо (идентификатор)
begin
CRES := GET_OPTIONS_STR(SCODE => SPARAMCODE,
NCOMP_VERS => NCOMPANY);
if (CRES is null) then
P_EXCEPTION(0, 'Пользовательский параметр не указан.');
end if;
end GET_JUR_PERS_PRM;
/* Находим юр. лицо */
FIND_JURPERSONS_MAIN(NFLAG_SMART => 1, NCOMPANY => NCOMPANY, SJUR_PERS => SJUR_PERS, NJUR_PERS => NJUR_PERS);
/* Формируем XML */
PKG_XFAST.PROLOGUE(ITYPE => PKG_XFAST.CONTENT_);
PKG_XFAST.DOWN_NODE(SNAME => 'DATA');
PKG_XFAST.DOWN_NODE(SNAME => 'JURPERS');
PKG_XFAST.VALUE(SVALUE => SJUR_PERS);
PKG_XFAST.UP();
PKG_XFAST.DOWN_NODE(SNAME => 'MONTH');
PKG_XFAST.VALUE(NVALUE => EXTRACT(month from sysdate));
PKG_XFAST.UP();
PKG_XFAST.DOWN_NODE(SNAME => 'YEAR');
PKG_XFAST.VALUE(NVALUE => EXTRACT(year from sysdate));
PKG_XFAST.UP();
PKG_XFAST.UP();
/* Сериализуем в clob */
COUT := PKG_XFAST.SERIALIZE_TO_CLOB();
PKG_XFAST.EPILOGUE();
end GET_DEFAULT_FP;
/* Формирование строки с кол-вом часов */
function HOURS_STR
@ -50,28 +82,136 @@ create or replace package body PKG_P8PANELS_EQUIPSRV as
NHOURS in number -- Кол-во часов
) return varchar2 -- Строка с кол-вом часов
is
SRESULT PKG_STD.tSTRING; -- Строка результат
SRESULT PKG_STD.TSTRING; -- Строка результат
begin
if (MOD(NHOURS, 10) = 1 and MOD(NHOURS, 100) != 11) then
if ((mod(NHOURS, 10) = 1) and (mod(NHOURS, 100) != 11)) then
SRESULT := NHOURS || ' час';
elsif ((MOD(NHOURS, 10) = 2 and MOD(NHOURS, 100) != 12)
or (MOD(NHOURS, 10) = 3 and MOD(NHOURS, 100) != 13)
or (MOD(NHOURS, 10) = 4 and MOD(NHOURS, 100) != 14)) then
elsif (((mod(NHOURS, 10) = 2) and (mod(NHOURS, 100) != 12)) or ((mod(NHOURS, 10) = 3) and (mod(NHOURS, 100) != 13)) or
((mod(NHOURS, 10) = 4) and (mod(NHOURS, 100) != 14))) then
SRESULT := NHOURS || ' часа';
else
SRESULT := NHOURS || ' часов';
end if;
/* Возвращаем результат */
return SRESULT;
end HOURS_STR;
/* Отбор документов (ТОиР или Графики ремонтов) по дате */
procedure SELECT_EQUIPSRV
(
SBELONG in varchar2, -- Принадлежность к Юр. лицу
SPRODOBJ in varchar2, -- Производственный объект
STECHSERV in varchar2 := null, -- Техническая служба
SRESPDEP in varchar2 := null, -- Ответственное подразделение
STECHNAME in varchar2, -- Наименование объекта ремонта
SSRVKIND in varchar2, -- Код вида ремонта
NYEAR in number, -- Год
NMONTH in number, -- Месяц
NDAY in number := null, -- День
NWORKTYPE in number, -- Тип работы (0 - план, 1 - факт)
NIDENT out number -- Идентификатор буфера подобранных (списка отмеченных записей, null - не найдено)
)
is
NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Рег. номер организации
NSELECTLIST PKG_STD.TREF; -- Рег. номер добавленной записи буфера подобранных
SDATE PKG_STD.TSTRING; -- Строка даты
begin
/* Проверка на дату с днём */
if (NDAY is not null) then
SDATE := LPAD(TO_CHAR(NDAY), 2, '0') || '.' || LPAD(TO_CHAR(NMONTH), 2, '0') || '.' || NYEAR;
else
SDATE := LPAD(TO_CHAR(NMONTH), 2, '0') || '.' || NYEAR;
end if;
/* Если графики ТОиР */
if (NWORKTYPE = 0) then
for C in (select T.RN,
T.COMPANY
from EQTCHSRV T,
JURPERSONS J,
EQTECSRVKIND SK,
EQCONFIG C1,
EQCONFIG C2,
INS_DEPARTMENT DS,
INS_DEPARTMENT DR
where T.STATE in (1, 2)
and T.COMPANY = NCOMPANY
and T.JUR_PERS = J.RN
and J.CODE = SBELONG
and T.EQCONFIG = C1.RN
and C1.CODE = SPRODOBJ
and T.DEPTTCSRV = DS.RN
and (DS.CODE = STECHSERV or STECHSERV is null)
and T.DEPTRESP = DR.RN
and (DR.CODE = SRESPDEP or SRESPDEP is null)
and T.EQCONFIG_TECH = C2.RN
and C2.NAME = STECHNAME
and T.EQTECSRVKIND = SK.RN
and SK.CODE = SSRVKIND
and ((NDAY is not null and TO_DATE(SDATE, 'dd.mm.yyyy') between TRUNC(T.DATEPRD_BEG) and
TRUNC(T.DATEPRD_END)) or (NDAY is null and (SDATE = TO_CHAR(T.DATEPRD_BEG, 'mm.yyyy') or
SDATE = TO_CHAR(T.DATEPRD_END, 'mm.yyyy')))))
loop
/* Сформируем идентификатор буфера */
if (NIDENT is null) then
NIDENT := GEN_IDENT();
end if;
/* Добавим подобранное в список отмеченных записей */
P_SELECTLIST_BASE_INSERT(NIDENT => NIDENT,
NCOMPANY => C.COMPANY,
NDOCUMENT => C.RN,
SUNITCODE => 'EquipTechServices',
SACTIONCODE => null,
NCRN => null,
NDOCUMENT1 => null,
SUNITCODE1 => null,
SACTIONCODE1 => null,
NRN => NSELECTLIST);
end loop;
/* Иначе ремонтные ведомости */
else
for C in (select T.RN,
T.COMPANY
from EQRPSHEETS T,
JURPERSONS J,
EQTECSRVKIND SK,
EQCONFIG C
where T.STATE in (0, 2, 3)
and T.COMPANY = NCOMPANY
and T.JURPERSONS = J.RN
and J.CODE = SBELONG
and T.EQCONFIG = C.RN
and C.NAME = STECHNAME
and T.TECSRVKIND = SK.RN
and SK.CODE = SSRVKIND
and ((NDAY is not null and TO_DATE(SDATE, 'dd.mm.yyyy') between TRUNC(T.DATEFACT_BEG) and
TRUNC(T.DATEFACT_END)) or (NDAY is null and (SDATE = TO_CHAR(T.DATEFACT_BEG, 'mm.yyyy') or
SDATE = TO_CHAR(T.DATEFACT_END, 'mm.yyyy')))))
loop
/* Сформируем идентификатор буфера */
if (NIDENT is null) then
NIDENT := GEN_IDENT();
end if;
/* Добавим подобранное в список отмеченных записей */
P_SELECTLIST_BASE_INSERT(NIDENT => NIDENT,
NCOMPANY => C.COMPANY,
NDOCUMENT => C.RN,
SUNITCODE => 'EquipRepairSheets',
SACTIONCODE => null,
NCRN => null,
NDOCUMENT1 => null,
SUNITCODE1 => null,
SACTIONCODE1 => null,
NRN => NSELECTLIST);
end loop;
end if;
end SELECT_EQUIPSRV;
/* Выполнение работ по ТОиР */
procedure EQUIPSRV_GRID
(
SBELONG in varchar2, -- Принадлежность к Юр. лицу
SPRODOBJ in varchar2, -- Производственный объект
STECHSERV in varchar2, -- Техническая служба
SRESPDEP in varchar2, -- Ответственное подразделение
STECHSERV in varchar2 := null, -- Техническая служба
SRESPDEP in varchar2 := null, -- Ответственное подразделение
NFROMMONTH in number, -- Месяц начала периода
NFROMYEAR in number, -- Год начала периода
NTOMONTH in number, -- Месяц окончания периода
@ -86,37 +226,32 @@ create or replace package body PKG_P8PANELS_EQUIPSRV as
RDG_ROW0 PKG_P8PANELS_VISUAL.TROW; -- Строка таблицы0
RDG_ROW PKG_P8PANELS_VISUAL.TROW; -- Строка таблицы
RDG_ROW2 PKG_P8PANELS_VISUAL.TROW; -- Строка таблицы2
NCURYEAR PKG_STD.tNUMBER; -- Текущий год
NCURMONTH PKG_STD.tNUMBER; -- Текущий месяц
NTOTALDAYS PKG_STD.tNUMBER; -- Дней в текущем месяце
NCURYEAR PKG_STD.TNUMBER; -- Текущий год
NCURMONTH PKG_STD.TNUMBER; -- Текущий месяц
NTOTALDAYS PKG_STD.TNUMBER; -- Дней в текущем месяце
SCURTECHOBJ PKG_STD.TSTRING := null; -- Текущий технический объект
SCURTSKCODE PKG_STD.TSTRING := null; -- Текущий вид ремонта
NFROMDATE date := TO_DATE('01.'
|| LPAD(TO_CHAR(NFROMMONTH), 2, '0')
|| '.' || TO_CHAR(NFROMYEAR),
'dd.mm.yyyy'); -- Дата начала периода
NTODATE date := LAST_DAY(TO_DATE('01.'
|| LPAD(TO_CHAR(NTOMONTH), 2, '0')
|| '.' || TO_CHAR(NTOYEAR),
'dd.mm.yyyy')); -- Дата конца периода
NMS PKG_STD.tNUMBER; -- Месяц начала в цикле года
NME PKG_STD.tNUMBER; -- Месяц окончания в цикле года
NYEAR_PLAN PKG_STD.tNUMBER; -- Год план
NMONTH_PLAN PKG_STD.tNUMBER; -- Месяц план
NDAY_PLAN PKG_STD.tNUMBER; -- День план
NYEAR_FACT PKG_STD.tNUMBER; -- Год факт
NMONTH_FACT PKG_STD.tNUMBER; -- Месяц факт
NDAY_FACT PKG_STD.tNUMBER; -- День факт
NFROMDATE PKG_STD.TLDATE; -- Дата начала периода
NTODATE PKG_STD.TLDATE; -- Дата конца периода
NMS PKG_STD.TNUMBER; -- Месяц начала в цикле года
NME PKG_STD.TNUMBER; -- Месяц окончания в цикле года
NYEAR_PLAN PKG_STD.TNUMBER; -- Год план
NMONTH_PLAN PKG_STD.TNUMBER; -- Месяц план
NDAY_PLAN PKG_STD.TNUMBER; -- День план
NYEAR_FACT PKG_STD.TNUMBER; -- Год факт
NMONTH_FACT PKG_STD.TNUMBER; -- Месяц факт
NDAY_FACT PKG_STD.TNUMBER; -- День факт
SPERIODNAME PKG_STD.TSTRING; -- Имя периода
SFACT_CLR PKG_STD.TSTRING; -- Цвет закрашивания фактических дат
NROWS PKG_STD.tNUMBER := 0; -- Кол-во строк в курсоре
NWORKPERDAY PKG_STD.tNUMBER(17,2) := null; -- Работы в день
CR PKG_STD.TSTRING;
SGROUP_FILLED PKG_STD.tLSTRING; -- Группы, заполненные строками план/факт
SCOLS PKG_STD.tLSTRING; -- Заполнение периодов работ
YM PKG_CONTVALLOC1S.tCONTAINER; -- Коллекция для подсчёта работ за месяц
MCLR PKG_CONTVALLOC1S.tCONTAINER; -- Коллекция для закрашивания месяцев
NROWS PKG_STD.TNUMBER := 0; -- Кол-во строк в курсоре
NWORKPERDAY PKG_STD.TNUMBER(17,2) := null; -- Работы в день
SGROUP_FILLED PKG_STD.TLSTRING; -- Группы, заполненные строками план/факт
SCOLS PKG_STD.TLSTRING; -- Заполнение периодов работ
YM PKG_CONTVALLOC1S.TCONTAINER; -- Коллекция для подсчёта работ за месяц
MCLR PKG_CONTVALLOC1S.TCONTAINER; -- Коллекция для закрашивания месяцев
CR PKG_STD.TSTRING; -- Текущий ключ коллекции MCLR
/* Курсор с работами ТОиР */
cursor C1 is
select TT.NEQV_RN,
TT.NEQS_RN,
@ -135,14 +270,11 @@ create or replace package body PKG_P8PANELS_EQUIPSRV as
EQJ.DATEFACT_END DDATEFACTEND,
EK.CODE STECSRVKINDCODE,
EK.NAME STECSRVKINDNAME,
coalesce(EW.NSUM,
(TT.DATEPRD_END - TT.DATEPRD_BEG) * 24) NSUMWORKPLAN,
coalesce(EWJ.NSUMF,
(EQJ.DATEFACT_END - EQJ.DATEFACT_BEG) * 24) NSUMWORKFACT
from
(select B.*,
C.RN nWRK_RN,
C.PRN nWRK_PRN,
COALESCE(EW.NSUM, (TT.DATEPRD_END - TT.DATEPRD_BEG) * 24) NSUMWORKPLAN,
COALESCE(EWJ.NSUMF, (EQJ.DATEFACT_END - EQJ.DATEFACT_BEG) * 24) NSUMWORKFACT
from (select B.*,
C.RN NWRK_RN,
C.PRN NWRK_PRN,
C.NAME_WORK,
C.DATEPLAN_BEG,
C.DATEPLAN_END,
@ -151,25 +283,25 @@ create or replace package body PKG_P8PANELS_EQUIPSRV as
C.DEPTPERF,
C.DEPTTCSRV,
C.RESP_AGN
from (select EQV.RN nEQV_RN,
from (select EQV.RN NEQV_RN,
EQV.COMPANY,
EQV.JUR_PERS,
EQV.STATE,
EQV.DATEPRD_BEG,
EQV.DATEPRD_END,
EQS.RN nEQS_RN
from EQTCHSRV EQV, -- Графики ТОиР
EQS.RN NEQS_RN
from EQTCHSRV EQV,
DOCLINKS DL,
EQRPSHEETS EQS -- Ремонтные ведомости
EQRPSHEETS EQS
where EQV.RN = DL.IN_DOCUMENT(+)
and DL.OUT_UNITCODE(+) = 'EquipRepairSheets'
and DL.OUT_DOCUMENT = EQS.RN(+)) B,
EQTCHSRWRK C
where B.nEQV_RN = C.PRN (+)
where B.NEQV_RN = C.PRN(+)
union all
select B.*,
C.RN nWRK_RN,
C.PRN nWRK_PRN,
C.RN NWRK_RN,
C.PRN NWRK_PRN,
C.NAME_WORK,
C.DATEPLAN_BEG,
C.DATEPLAN_END,
@ -178,20 +310,20 @@ create or replace package body PKG_P8PANELS_EQUIPSRV as
C.DEPTPERF,
null DEPTTCSRV,
C.RESP_AGN
from (select null nEQV_RN,
from (select null NEQV_RN,
EQS.COMPANY,
EQS.JURPERSONS JUR_PERS,
EQS.STATE,
EQS.DATEPLAN_BEG,
EQS.DATEPLAN_END,
EQS.RN nEQS_RN
from EQRPSHEETS EQS -- Ремонтные ведомости
EQS.RN NEQS_RN
from EQRPSHEETS EQS
where not exists (select 1
from DOCLINKS DL
where DL.OUT_DOCUMENT = EQS.RN
and DL.IN_UNITCODE = 'EquipTechServices')) B,
EQRPSHWRK C
where B.nEQS_RN = C.PRN (+)) TT,
where B.NEQS_RN = C.PRN(+)) TT,
EQTECSRVKIND EK,
JURPERSONS JP,
EQCONFIG EC1,
@ -200,16 +332,16 @@ create or replace package body PKG_P8PANELS_EQUIPSRV as
INS_DEPARTMENT DR,
DOCLINKS DL,
EQTECSRVJRNL EQJ,
(select t.prn,
sum(t.Worktimeplan * t.perform_quant) NSUM
from EQTCHSRWRC t
group by t.prn) EW,
(select t.prn,
sum(t.worktimefact * t.quantfact) NSUMF
from EQTCHSRJRNLWRC t
group by t.prn) EWJ
(select T.PRN,
sum(T.WORKTIMEPLAN * T.PERFORM_QUANT) NSUM
from EQTCHSRWRC T
group by T.PRN) EW,
(select T.PRN,
sum(T.WORKTIMEFACT * T.QUANTFACT) NSUMF
from EQTCHSRJRNLWRC T
group by T.PRN) EWJ
where TT.COMPANY = NCOMPANY
and ((TT.state in (1,2) and nEQV_RN is not null) or (TT.state in (0,2,3) and nEQV_RN is null))
and ((TT.STATE in (1, 2) and NEQV_RN is not null) or (TT.STATE in (0, 2, 3) and NEQV_RN is null))
and TT.DATEPRD_BEG >= NFROMDATE
and TT.DATEPRD_END <= NTODATE
and JP.CODE = SBELONG
@ -223,10 +355,16 @@ create or replace package body PKG_P8PANELS_EQUIPSRV as
and EQJ.RN = EWJ.PRN(+)
and TT.TECSRVKIND = EK.RN(+)
and TT.NWRK_RN = DL.IN_DOCUMENT(+)
and ((DL.OUT_UNITCODE = 'EquipTechServiceJournal' and DL.RN is not null) or (DL.OUT_UNITCODE is null and DL.RN is null))
and ((DL.OUT_UNITCODE = 'EquipTechServiceJournal' and DL.RN is not null) or
(DL.OUT_UNITCODE is null and DL.RN is null))
and DL.OUT_DOCUMENT = EQJ.RN(+)
order by EC2.NAME, EK.CODE;
order by EC2.NAME,
EK.CODE;
begin
/* Определим дату начала периода */
NFROMDATE := TO_DATE('01.' || LPAD(TO_CHAR(NFROMMONTH), 2, '0') || '.' || TO_CHAR(NFROMYEAR), 'dd.mm.yyyy');
/* Определим дату конца периода */
NTODATE := LAST_DAY(TO_DATE('01.' || LPAD(TO_CHAR(NTOMONTH), 2, '0') || '.' || TO_CHAR(NTOYEAR), 'dd.mm.yyyy'));
/* Инициализируем таблицу данных */
RDG := PKG_P8PANELS_VISUAL.TDATA_GRID_MAKE();
/* Формируем структуру заголовка */
@ -236,7 +374,7 @@ create or replace package body PKG_P8PANELS_EQUIPSRV as
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR);
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SINFO',
SCAPTION => 'Информация',
SCAPTION => 'Объект ремонта',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR);
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SINFO2',
@ -319,12 +457,12 @@ create or replace package body PKG_P8PANELS_EQUIPSRV as
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BVISIBLE => false);
/* Очистка коллекций */
PKG_CONTVALLOC1S.PURGE(YM);
PKG_CONTVALLOC1S.PURGE(MCLR);
PKG_CONTVALLOC1S.PURGE(RCONTAINER => YM);
PKG_CONTVALLOC1S.PURGE(RCONTAINER => MCLR);
/* Текущий год */
NCURYEAR := EXTRACT(year from sysdate);
/* Текущий месяц */
NCURMONTH := EXTRACT(month from sysdate);
/* Цикл по годам периода */
for Y in NFROMYEAR .. NTOYEAR
loop
@ -335,7 +473,7 @@ create or replace package body PKG_P8PANELS_EQUIPSRV as
if (Y = NFROMYEAR) then
NMS := NFROMMONTH;
NME := 12;
elsif (NFROMYEAR < Y and Y < NTOYEAR) then
elsif ((NFROMYEAR < Y) and (Y < NTOYEAR)) then
NMS := 1;
NME := 12;
elsif (Y = NTOYEAR) then
@ -343,62 +481,66 @@ create or replace package body PKG_P8PANELS_EQUIPSRV as
NME := NTOMONTH;
end if;
end if;
/* Цикл по месяцам года */
for M in NMS .. NME
loop
PKG_CONTVALLOC1S.PUTN(YM, '_' || TO_CHAR(Y) || '_' || TO_CHAR(M) || '_P', 0);
PKG_CONTVALLOC1S.PUTN(YM, '_' || TO_CHAR(Y) || '_' || TO_CHAR(M) || '_F', 0);
if (Y = NCURYEAR and M = NCURMONTH) then
PKG_CONTVALLOC1S.PUTN(RCONTAINER => YM, SROWID => '_' || TO_CHAR(Y) || '_' || TO_CHAR(M) || '_P', NVALUE => 0);
PKG_CONTVALLOC1S.PUTN(RCONTAINER => YM, SROWID => '_' || TO_CHAR(Y) || '_' || TO_CHAR(M) || '_F', NVALUE => 0);
/* Находим текущий месяц и делаем его развёрнутым по дням */
if ((Y = NCURYEAR) and (M = NCURMONTH)) then
BEXPANDED := true;
else
BEXPANDED := false;
end if;
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => '_' || TO_CHAR(Y) || '_' || TO_CHAR(M),
SCAPTION => LPAD(TO_CHAR(M), 2, '0') || ' ' || TO_CHAR(Y),
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
BEXPANDABLE => true,
BEXPANDED => BEXPANDED);
NTOTALDAYS := to_number(to_char(LAST_DAY(TO_DATE('01.' || LPAD(TO_CHAR(M), 2, '0') || '.' || TO_CHAR(Y), 'dd.mm.yyyy')),'dd'), '99');
/* Подсчёт кол-ва дней в месяце */
NTOTALDAYS := TO_NUMBER(TO_CHAR(LAST_DAY(TO_DATE('01.' || LPAD(TO_CHAR(M), 2, '0') || '.' || TO_CHAR(Y),
'dd.mm.yyyy')),
'dd'),
'99');
/* Цикл по дням месяца */
for D in 1 .. NTOTALDAYS
loop
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => '_' || TO_CHAR(Y) || '_' || TO_CHAR(M) || '_' || TO_CHAR(D),
SNAME => '_' || TO_CHAR(Y) || '_' || TO_CHAR(M) || '_' ||
TO_CHAR(D),
SCAPTION => TO_CHAR(D, '99'),
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
SPARENT => '_' || TO_CHAR(Y) || '_' || TO_CHAR(M));
end loop;
end loop;
end loop;
/* Подсчёт кол-ва записей в курсоре */
for Q1 in C1
loop
NROWS := NROWS + 1;
end loop;
/* Цикл по курсору */
for QQ in C1
loop
NROWS := NROWS - 1;
if (SCURTECHOBJ != QQ.STECHOBJNAME or SCURTECHOBJ is null) then
/* Если новый объект ремонта */
if ((SCURTECHOBJ != QQ.STECHOBJNAME) or (SCURTECHOBJ is null)) then
/* Если строка с трудоёмкостью по объекту ремонта сформирована */
if (RDG_ROW0.RCOLS is not null) then
/* Цикл по годам периода */
for Y in NFROMYEAR .. NTOYEAR
loop
/* Если отчёт в пределах года */
if (NFROMYEAR = NTOYEAR) then
NMS := NFROMMONTH;
NME := NTOMONTH;
/* Иначе вычисляем кол-во месяцев в каждом году периода отчёта*/
else
if (Y = NFROMYEAR) then
NMS := NFROMMONTH;
NME := 12;
elsif (NFROMYEAR < Y and Y < NTOYEAR) then
elsif ((NFROMYEAR < Y) and (Y < NTOYEAR)) then
NMS := 1;
NME := 12;
elsif (Y = NTOYEAR) then
@ -406,21 +548,26 @@ create or replace package body PKG_P8PANELS_EQUIPSRV as
NME := NTOMONTH;
end if;
end if;
/* Цикл по месяцам года */
/* Цикл по месяцам года, заполнение трудоёмкости с привязкой к месяцу */
for M in NMS .. NME
loop
SPERIODNAME := '_' || TO_CHAR(Y) || '_' || TO_CHAR(M);
PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW0,
SNAME => SPERIODNAME,
SVALUE => 'план: ' || HOURS_STR(PKG_CONTVALLOC1S.GETN(YM, SPERIODNAME || '_P')) || ' факт: ' || HOURS_STR(PKG_CONTVALLOC1S.GETN(YM, SPERIODNAME || '_F')));
PKG_CONTVALLOC1S.PUTN(YM, SPERIODNAME || '_P', 0);
PKG_CONTVALLOC1S.PUTN(YM, SPERIODNAME || '_F', 0);
SVALUE => 'план: ' ||
HOURS_STR(PKG_CONTVALLOC1S.GETN(YM, SPERIODNAME || '_P')) ||
' факт: ' ||
HOURS_STR(PKG_CONTVALLOC1S.GETN(YM, SPERIODNAME || '_F')));
/* Добавление в коллекцию трудоёмкость план */
PKG_CONTVALLOC1S.PUTN(RCONTAINER => YM, SROWID => SPERIODNAME || '_P', NVALUE => 0);
/* Добавление в коллекцию трудоёмкость факт */
PKG_CONTVALLOC1S.PUTN(RCONTAINER => YM, SROWID => SPERIODNAME || '_F', NVALUE => 0);
end loop;
end loop;
/* Добавление строки с трудоёмкостью */
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW0);
end if;
/* Добавление группы с объектом ремонта */
SCURTECHOBJ := QQ.STECHOBJNAME;
SPRJ_GROUP_NAME := SCURTECHOBJ;
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_GROUP(RDATA_GRID => RDG,
@ -433,121 +580,141 @@ create or replace package body PKG_P8PANELS_EQUIPSRV as
/* Формируем имя группы для вида ремонта */
SCURTSKCODE := SCURTECHOBJ || '_' || QQ.STECSRVKINDCODE;
/* Если по данной группе еще нет строк плана и факта */
if (STRIN(sSUBSTR => SCURTSKCODE, sSOURCE => SGROUP_FILLED, sDELIM => ';') = 0) then
if (STRIN(SSUBSTR => SCURTSKCODE, SSOURCE => SGROUP_FILLED, SDELIM => ';') = 0) then
/* Добавляем строку плана */
if (RDG_ROW.RCOLS is not null) then
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
end if;
/* Добавляем строку факта */
if (RDG_ROW2.RCOLS is not null) then
CR := PKG_CONTVALLOC1S.FIRST_(MCLR);
CR := PKG_CONTVALLOC1S.FIRST_(RCONTAINER => MCLR);
/* Цикл по коллекции для закрашивания месяцев */
for Z in 1 .. PKG_CONTVALLOC1S.COUNT_(MCLR)
for Z in 1 .. PKG_CONTVALLOC1S.COUNT_(RCONTAINER => MCLR)
loop
PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW2, SNAME => CR, SVALUE => PKG_CONTVALLOC1S.GETS(MCLR, CR));
CR := PKG_CONTVALLOC1S.NEXT_(MCLR, CR);
PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW2,
SNAME => CR,
SVALUE => PKG_CONTVALLOC1S.GETS(RCONTAINER => MCLR, SROWID => CR));
CR := PKG_CONTVALLOC1S.NEXT_(RCONTAINER => MCLR, SROWID => CR);
end loop;
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW2);
end if;
PKG_CONTVALLOC1S.PURGE(MCLR);
PKG_CONTVALLOC1S.PURGE(RCONTAINER => MCLR);
/* Добвим группу для вида ремонта */
SPRJ_GROUP_NAME := SCURTSKCODE;
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_GROUP(RDATA_GRID => RDG,
SNAME => SPRJ_GROUP_NAME,
SCAPTION => QQ.STECSRVKINDCODE,
BEXPANDABLE => false);
/* Строка плана */
RDG_ROW := PKG_P8PANELS_VISUAL.TROW_MAKE(SGROUP => SPRJ_GROUP_NAME);
PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'STEST', SVALUE => QQ.STECSRVKINDCODE);
PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SINFO2', SVALUE => 'План');
/* Строка факта */
RDG_ROW2 := PKG_P8PANELS_VISUAL.TROW_MAKE(SGROUP => SPRJ_GROUP_NAME);
PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW2, SNAME => 'SINFO2', SVALUE => 'Факт');
/* Добавляем в заполненные группы */
SGROUP_FILLED := SGROUP_FILLED || SPRJ_GROUP_NAME || ';';
end if;
/* Плановые работы */
if (QQ.NEQV_RN is not null) then
for x in 0 .. trunc(QQ.DDATEPLANEND) - trunc(QQ.DDATEPLANBEG)
/* Цикл по периоду */
for X in 0 .. TRUNC(QQ.DDATEPLANEND) - TRUNC(QQ.DDATEPLANBEG)
loop
NYEAR_PLAN := EXTRACT(year from QQ.DDATEPLANBEG + x);
NMONTH_PLAN := EXTRACT(month from QQ.DDATEPLANBEG + x);
NDAY_PLAN := EXTRACT(day from QQ.DDATEPLANBEG + x);
if (x = 0) then
NYEAR_PLAN := EXTRACT(year from QQ.DDATEPLANBEG + X);
NMONTH_PLAN := EXTRACT(month from QQ.DDATEPLANBEG + X);
NDAY_PLAN := EXTRACT(day from QQ.DDATEPLANBEG + X);
/* Если первый день периода */
if (X = 0) then
SPERIODNAME := '_' || TO_CHAR(NYEAR_PLAN) || '_' || NMONTH_PLAN;
/* Подсчёт трудоёмкости за месяц */
if (QQ.NSUMWORKPLAN is not null) then
PKG_CONTVALLOC1S.PUTN(YM, SPERIODNAME || '_P', PKG_CONTVALLOC1S.GETN(YM, SPERIODNAME || '_P') + QQ.NSUMWORKPLAN);
PKG_CONTVALLOC1S.PUTN(RCONTAINER => YM,
SROWID => SPERIODNAME || '_P',
NVALUE => PKG_CONTVALLOC1S.GETN(RCONTAINER => YM, SROWID => SPERIODNAME || '_P') +
QQ.NSUMWORKPLAN);
end if;
if (STRIN(sSUBSTR => SPRJ_GROUP_NAME || ' ' || SPERIODNAME || ' PLAN', sSOURCE => SCOLS, sDELIM => ';') = 0) then
/* Закрашивание месяца плана синим */
if (STRIN(SSUBSTR => SPRJ_GROUP_NAME || ' ' || SPERIODNAME || ' PLAN', SSOURCE => SCOLS, SDELIM => ';') = 0) then
PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => SPERIODNAME, SVALUE => 'blue');
SCOLS := SCOLS || SPRJ_GROUP_NAME || ' ' || SPERIODNAME || ' PLAN;';
end if;
end if;
SPERIODNAME := '_' || TO_CHAR(NYEAR_PLAN) || '_' || TO_CHAR(NMONTH_PLAN) || '_' || TO_CHAR(NDAY_PLAN);
if (STRIN(sSUBSTR => SPRJ_GROUP_NAME || ' ' || SPERIODNAME || ' PLAN', sSOURCE => SCOLS, sDELIM => ';') = 0) then
/* Закрашивание дня плана синим */
if (STRIN(SSUBSTR => SPRJ_GROUP_NAME || ' ' || SPERIODNAME || ' PLAN', SSOURCE => SCOLS, SDELIM => ';') = 0) then
PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW, SNAME => SPERIODNAME, SVALUE => 'blue');
SCOLS := SCOLS || SPRJ_GROUP_NAME || ' ' || SPERIODNAME || ' PLAN;';
end if;
end loop;
end if;
/* Фактические и внеплановые работы */
if (QQ.DDATEFACTEND is not null and QQ.DDATEFACTBEG is not null) then
if (QQ.nEQV_RN is not null) then
if ((QQ.DDATEFACTEND is not null) and (QQ.DDATEFACTBEG is not null)) then
/* Фактические - зелёный, внеплановые - красный */
if (QQ.NEQV_RN is not null) then
SFACT_CLR := 'green';
else
SFACT_CLR := 'red';
end if;
NWORKPERDAY := null;
/* Если период не в одном месяце, то считаем трудоёмкость в день */
if (EXTRACT(month from QQ.DDATEFACTBEG) != EXTRACT(month from QQ.DDATEFACTEND)) then
NWORKPERDAY := QQ.NSUMWORKFACT/(round(QQ.DDATEFACTEND - QQ.DDATEFACTBEG) + 1);
NWORKPERDAY := QQ.NSUMWORKFACT / (ROUND(QQ.DDATEFACTEND - QQ.DDATEFACTBEG) + 1);
NCURMONTH := EXTRACT(month from QQ.DDATEFACTBEG);
end if;
for x in 0 .. trunc(QQ.DDATEFACTEND) - trunc(QQ.DDATEFACTBEG)
/* Цикл по периоду */
for X in 0 .. TRUNC(QQ.DDATEFACTEND) - TRUNC(QQ.DDATEFACTBEG)
loop
NYEAR_FACT := EXTRACT(year from QQ.DDATEFACTBEG + x);
NMONTH_FACT := EXTRACT(month from QQ.DDATEFACTBEG + x);
NDAY_FACT := EXTRACT(day from QQ.DDATEFACTBEG + x);
if (x = 0 or NCURMONTH != NMONTH_FACT) then
NYEAR_FACT := EXTRACT(year from QQ.DDATEFACTBEG + X);
NMONTH_FACT := EXTRACT(month from QQ.DDATEFACTBEG + X);
NDAY_FACT := EXTRACT(day from QQ.DDATEFACTBEG + X);
/* Если первый день периода или следующий месяц периода */
if ((X = 0) or (NCURMONTH != NMONTH_FACT)) then
/* Обновляется текущий месяц */
if (NCURMONTH != NMONTH_FACT) then
NCURMONTH := NMONTH_FACT;
end if;
SPERIODNAME := '_' || TO_CHAR(NYEAR_FACT) || '_' || NMONTH_FACT;
if (QQ.NSUMWORKFACT is not null and NWORKPERDAY is null) then
PKG_CONTVALLOC1S.PUTN(YM, SPERIODNAME || '_F', PKG_CONTVALLOC1S.GETN(YM, SPERIODNAME || '_F') + QQ.NSUMWORKFACT);
/* Подсчёт трудоёмкости за месяц если период в одном месяце */
if ((QQ.NSUMWORKFACT is not null) and (NWORKPERDAY is null)) then
PKG_CONTVALLOC1S.PUTN(RCONTAINER => YM,
SROWID => SPERIODNAME || '_F',
NVALUE => PKG_CONTVALLOC1S.GETN(RCONTAINER => YM, SROWID => SPERIODNAME || '_F') +
QQ.NSUMWORKFACT);
end if;
/* Добавление в коллекцию окрашивания месяца */
if (PKG_CONTVALLOC1S.EXISTS_(rCONTAINER => MCLR, sROWID => SPERIODNAME) = false) then
PKG_CONTVALLOC1S.PUTS(MCLR, SPERIODNAME, SFACT_CLR);
if (PKG_CONTVALLOC1S.EXISTS_(RCONTAINER => MCLR, SROWID => SPERIODNAME) = false) then
PKG_CONTVALLOC1S.PUTS(RCONTAINER => MCLR, SROWID => SPERIODNAME, SVALUE => SFACT_CLR);
else
/* Если второй цвет для месяца */
if (STRIN(trim(SFACT_CLR), trim(PKG_CONTVALLOC1S.GETS(MCLR, SPERIODNAME))) = 0) then
PKG_CONTVALLOC1S.PUTS(MCLR, SPERIODNAME, PKG_CONTVALLOC1S.GETS(MCLR, SPERIODNAME) || ' ' || SFACT_CLR);
PKG_CONTVALLOC1S.PUTS(RCONTAINER => MCLR,
SROWID => SPERIODNAME,
SVALUE => PKG_CONTVALLOC1S.GETS(RCONTAINER => MCLR, SROWID => SPERIODNAME) || ' ' ||
SFACT_CLR);
end if;
end if;
end if;
/* Подсчёт трудоёмкости за месяц если период не в одном месяце */
if (NWORKPERDAY is not null) then
PKG_CONTVALLOC1S.PUTN(YM, SPERIODNAME || '_F', PKG_CONTVALLOC1S.GETN(YM, SPERIODNAME || '_F') + NWORKPERDAY);
PKG_CONTVALLOC1S.PUTN(RCONTAINER => YM,
SROWID => SPERIODNAME || '_F',
NVALUE => PKG_CONTVALLOC1S.GETN(RCONTAINER => YM, SROWID => SPERIODNAME || '_F') +
NWORKPERDAY);
end if;
SPERIODNAME := '_' || TO_CHAR(NYEAR_FACT) || '_' || TO_CHAR(NMONTH_FACT) || '_' || TO_CHAR(NDAY_FACT);
/* Добавление окрашивания дней факта */
if (PKG_CONTVALLOC1S.EXISTS_(rCONTAINER => MCLR, sROWID => SPERIODNAME) = false) then
PKG_CONTVALLOC1S.PUTS(MCLR, SPERIODNAME, SFACT_CLR);
/* Добавление в коллекцию окрашивания дней факта */
if (PKG_CONTVALLOC1S.EXISTS_(RCONTAINER => MCLR, SROWID => SPERIODNAME) = false) then
PKG_CONTVALLOC1S.PUTS(RCONTAINER => MCLR, SROWID => SPERIODNAME, SVALUE => SFACT_CLR);
else
if (trim(PKG_CONTVALLOC1S.GETS(MCLR, SPERIODNAME)) = 'green' and trim(SFACT_CLR) = 'red') then
PKG_CONTVALLOC1S.PUTS(MCLR, SPERIODNAME, SFACT_CLR);
/* Если второй цвет для месяца */
if ((trim(PKG_CONTVALLOC1S.GETS(RCONTAINER => MCLR, SROWID => SPERIODNAME)) = 'green') and
(trim(SFACT_CLR) = 'red')) then
PKG_CONTVALLOC1S.PUTS(RCONTAINER => MCLR, SROWID => SPERIODNAME, SVALUE => SFACT_CLR);
end if;
end if;
end loop;
end if;
if (RDG_ROW0.RCOLS is not null and NROWS = 0) then
if ((RDG_ROW0.RCOLS is not null) and (NROWS = 0)) then
/* Цикл по годам периода */
for Y in NFROMYEAR .. NTOYEAR
loop
@ -558,7 +725,7 @@ create or replace package body PKG_P8PANELS_EQUIPSRV as
if (Y = NFROMYEAR) then
NMS := NFROMMONTH;
NME := 12;
elsif (NFROMYEAR < Y and Y < NTOYEAR) then
elsif ((NFROMYEAR < Y) and (Y < NTOYEAR)) then
NMS := 1;
NME := 12;
elsif (Y = NTOYEAR) then
@ -566,37 +733,43 @@ create or replace package body PKG_P8PANELS_EQUIPSRV as
NME := NTOMONTH;
end if;
end if;
/* Цикл по месяцам года */
for M in NMS .. NME
loop
SPERIODNAME := '_' || TO_CHAR(Y) || '_' || TO_CHAR(M);
PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW0,
SNAME => SPERIODNAME,
SVALUE => 'план: ' || HOURS_STR(PKG_CONTVALLOC1S.GETN(YM, SPERIODNAME || '_P')) || ' факт: ' || HOURS_STR(PKG_CONTVALLOC1S.GETN(YM, SPERIODNAME || '_F')));
SVALUE => 'план: ' ||
HOURS_STR(NHOURS => PKG_CONTVALLOC1S.GETN(RCONTAINER => YM,
SROWID => SPERIODNAME || '_P')) ||
' факт: ' ||
HOURS_STR(NHOURS => PKG_CONTVALLOC1S.GETN(RCONTAINER => YM,
SROWID => SPERIODNAME || '_F')));
end loop;
end loop;
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW0);
end if;
/* План для последней записи */
if (RDG_ROW.RCOLS is not null and NROWS = 0) then
if ((RDG_ROW.RCOLS is not null) and (NROWS = 0)) then
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
end if;
/* Факт для последней записи */
if (RDG_ROW2.RCOLS is not null and NROWS = 0) then
CR := PKG_CONTVALLOC1S.FIRST_(MCLR);
for Z in 1 .. PKG_CONTVALLOC1S.COUNT_(MCLR)
if ((RDG_ROW2.RCOLS is not null) and (NROWS = 0)) then
CR := PKG_CONTVALLOC1S.FIRST_(RCONTAINER => MCLR);
for Z in 1 .. PKG_CONTVALLOC1S.COUNT_(RCONTAINER => MCLR)
loop
PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW2, SNAME => CR, SVALUE => PKG_CONTVALLOC1S.GETS(MCLR, CR));
CR := PKG_CONTVALLOC1S.NEXT_(MCLR, cr);
PKG_P8PANELS_VISUAL.TROW_ADD_COL(RROW => RDG_ROW2,
SNAME => CR,
SVALUE => PKG_CONTVALLOC1S.GETS(RCONTAINER => MCLR, SROWID => CR));
CR := PKG_CONTVALLOC1S.NEXT_(RCONTAINER => MCLR, SROWID => CR);
end loop;
PKG_P8PANELS_VISUAL.TDATA_GRID_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW2);
end if;
end loop;
/* Сериализуем описание */
COUT := PKG_P8PANELS_VISUAL.TDATA_GRID_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => 1);
PKG_CONTVALLOC1S.PURGE(YM);
PKG_CONTVALLOC1S.PURGE(RCONTAINER => YM);
end EQUIPSRV_GRID;
end PKG_P8PANELS_EQUIPSRV;
/