diff --git a/app/panels/mech_rec_cost_prod_plans/hooks.js b/app/panels/mech_rec_cost_prod_plans/hooks.js
index 926fc8a..dd285c4 100644
--- a/app/panels/mech_rec_cost_prod_plans/hooks.js
+++ b/app/panels/mech_rec_cost_prod_plans/hooks.js
@@ -13,10 +13,14 @@ import React from "react"; //Классы React
//Тело модуля
//-----------
-//Клиентский отбор загруженных планов по поисковой фразе
+//Клиентский отбор каталогов по поисковой фразе и наличию планов
export const useFilteredPlanCtlgs = (planCtlgs, filter) => {
const filteredPlanCtlgs = React.useMemo(() => {
- return planCtlgs.filter(catalog => catalog.SNAME.toString().toLowerCase().includes(filter));
+ return planCtlgs.filter(
+ catalog =>
+ catalog.SNAME.toString().toLowerCase().includes(filter.ctlgName) &&
+ (filter.haveDocs ? catalog.NCOUNT_DOCS > 0 : catalog.NCOUNT_DOCS >= 0)
+ );
}, [planCtlgs, filter]);
return filteredPlanCtlgs;
diff --git a/app/panels/mech_rec_cost_prod_plans/mech_rec_cost_prod_plans.js b/app/panels/mech_rec_cost_prod_plans/mech_rec_cost_prod_plans.js
index bb2a489..b4e2b01 100644
--- a/app/panels/mech_rec_cost_prod_plans/mech_rec_cost_prod_plans.js
+++ b/app/panels/mech_rec_cost_prod_plans/mech_rec_cost_prod_plans.js
@@ -9,7 +9,23 @@
import React, { useContext, useState, useCallback, useEffect } from "react"; //Классы React
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,
+ FormGroup,
+ FormControlLabel,
+ Checkbox
+} from "@mui/material"; //Интерфейсные элементы
import { BackEndСtx } from "../../context/backend"; //Контекст взаимодействия с сервером
import { MessagingСtx } from "../../context/messaging"; //Контекст сообщений
import { P8P_GANTT_CONFIG_PROPS } from "../../config_wrapper"; //Подключение компонентов к настройкам приложения
@@ -21,6 +37,9 @@ import { useFilteredPlanCtlgs } from "./hooks"; //Вспомогательные
//Константы
//---------
+//Склонения для документов
+const DECLINATIONS = ["план", "плана", "планов"];
+
//Поля сортировки
const SORT_REP_DATE = "DREP_DATE";
const SORT_REP_DATE_TO = "DREP_DATE_TO";
@@ -34,13 +53,16 @@ const GANTT_WIDTH = "98vw";
//Стили
const STYLES = {
PLANS_FINDER: { marginTop: "10px", marginLeft: "10px", width: "93%" },
+ PLANS_CHECKBOX_HAVEDOCS: { alignContent: "space-around" },
+ PLANS_LIST_ITEM_ZERODOCS: { backgroundColor: "#ebecec" },
PLANS_LIST_ITEM_PRIMARY: { wordWrap: "break-word" },
+ PLANS_LIST_ITEM_SECONDARY: { wordWrap: "break-word", fontSize: "0.6rem", textTransform: "uppercase" },
PLANS_BUTTON: { position: "absolute" },
PLANS_DRAWER: {
- minWidth: "250px",
+ width: "350px",
display: "inline-block",
flexShrink: 0,
- [`& .MuiDrawer-paper`]: { minWidth: "250px", display: "inline-block", boxSizing: "border-box" }
+ [`& .MuiDrawer-paper`]: { width: "350px", display: "inline-block", boxSizing: "border-box" }
},
GANTT_CONTAINER: { height: GANTT_HEIGHT, width: GANTT_WIDTH },
GANTT_TITLE: { paddingLeft: "100px", paddingRight: "120px" }
@@ -59,6 +81,26 @@ const parseProdPlanSpXML = async xmlDoc => {
return data.XDATA;
};
+//Форматирование для отображения количества документов
+const formatCountDocs = nCountDocs => {
+ //Получаем последнюю цифру в значении
+ let num = (nCountDocs % 100) % 10;
+ //Документов
+ if (nCountDocs > 10 && nCountDocs < 20) {
+ return `${nCountDocs} ${DECLINATIONS[2]}`;
+ }
+ //Документа
+ if (num > 1 && num < 5) {
+ return `${nCountDocs} ${DECLINATIONS[1]}`;
+ }
+ //Документ
+ if (num == 1) {
+ return `${nCountDocs} ${DECLINATIONS[0]}`;
+ }
+ //Документов
+ return `${nCountDocs} ${DECLINATIONS[2]}`;
+};
+
//Список каталогов планов
const PlanCtlgsList = ({ planCtlgs = [], selectedPlanCtlg, filter, setFilter, onClick } = {}) => {
//Генерация содержимого
@@ -67,18 +109,48 @@ const PlanCtlgsList = ({ planCtlgs = [], selectedPlanCtlg, filter, setFilter, on
{
- setFilter(event.target.value);
+ setFilter(pv => ({ ...pv, ctlgName: event.target.value }));
}}
>
+
+ {
+ setFilter(pv => ({ ...pv, haveDocs: event.target.checked }));
+ }}
+ />
+ }
+ label="Только с планами"
+ labelPlacement="end"
+ />
+
{planCtlgs.map(p => (
- (onClick ? onClick(p) : null)}>
- {p.SNAME}} />
+ (onClick ? onClick(p) : null)}
+ >
+ {p.SNAME}}
+ secondary={
+
+ {formatCountDocs(p.NCOUNT_DOCS)}
+
+ }
+ />
))}
@@ -116,9 +188,10 @@ const MechRecCostProdPlans = () => {
selectedPlanCtlgGanttDef: {},
selectedPlanCtlgSpecs: []
});
+ //Состояние для фильтра каталогов
+ const [filter, setFilter] = useState({ ctlgName: "", haveLinks: false });
- const [filter, setFilter] = useState("");
-
+ //Массив отфильтрованных каталогов
const filteredPlanCtgls = useFilteredPlanCtlgs(state.planCtlgs, filter);
//Подключение к контексту сообщений
diff --git a/db/PKG_P8PANELS_MECHREC.pck b/db/PKG_P8PANELS_MECHREC.pck
index 5ce95c9..4f733a8 100644
--- a/db/PKG_P8PANELS_MECHREC.pck
+++ b/db/PKG_P8PANELS_MECHREC.pck
@@ -207,8 +207,8 @@ create or replace package body PKG_P8PANELS_MECHREC as
CSQL clob; -- Буфер для запроса
ICURSOR integer; -- Курсор для исполнения запроса
/* Значения спецификации */
- NTASK_RN PKG_STD.TREF; -- Рег. номер спецификации
- NTASK_PRN PKG_STD.TREF; -- Рег. номер родителя спецификации
+ 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; -- Дата выпуска
@@ -557,7 +557,32 @@ create or replace package body PKG_P8PANELS_MECHREC as
PKG_XFAST.DOWN_NODE(SNAME => 'XDATA');
/* Цикл по планам и отчетам производства изделий */
for REC in (select T.RN as NRN,
- T.NAME as SNAME
+ T.NAME as SNAME,
+ (select count(P.RN)
+ from FCPRODPLAN P,
+ FINSTATE FS
+ where P.CRN = T.RN
+ 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)) as NCOUNT_DOCS
from ACATALOG T,
UNITLIST UL
where T.DOCNAME = 'CostProductPlans'
@@ -577,6 +602,7 @@ create or replace package body PKG_P8PANELS_MECHREC as
/* Описываем план */
PKG_XFAST.ATTR(SNAME => 'NRN', NVALUE => REC.NRN);
PKG_XFAST.ATTR(SNAME => 'SNAME', SVALUE => REC.SNAME);
+ PKG_XFAST.ATTR(SNAME => 'NCOUNT_DOCS', NVALUE => REC.NCOUNT_DOCS);
/* Закрываем план */
PKG_XFAST.UP();
end loop;