Compare commits
No commits in common. "d06f3a2db116753288a99742efbc1df9d5ff269f" and "624b1bd7beddc30e443ad1a13f9020d87f3c3c93" have entirely different histories.
d06f3a2db1
...
624b1bd7be
@ -1,279 +0,0 @@
|
|||||||
/*
|
|
||||||
Парус 8 - Панели мониторинга - ПУП - Выдача сменного задания на участок
|
|
||||||
Кастомные хуки
|
|
||||||
*/
|
|
||||||
|
|
||||||
//---------------------
|
|
||||||
//Подключение библиотек
|
|
||||||
//---------------------
|
|
||||||
|
|
||||||
import { useState, useCallback, useEffect, useContext } from "react"; //Классы React
|
|
||||||
import { BackEndСtx } from "../../context/backend"; //Контекст взаимодействия с сервером
|
|
||||||
import { NavigationCtx } from "../../context/navigation"; //Контекст навигации
|
|
||||||
import { object2Base64XML } from "../../core/utils"; //Вспомогательные функции
|
|
||||||
|
|
||||||
//---------
|
|
||||||
//Константы
|
|
||||||
//---------
|
|
||||||
|
|
||||||
//Размер страницы данных
|
|
||||||
const DATA_GRID_PAGE_SIZE = 50;
|
|
||||||
|
|
||||||
//---------------------------------------------
|
|
||||||
//Вспомогательные функции форматирования данных
|
|
||||||
//---------------------------------------------
|
|
||||||
|
|
||||||
//-----------
|
|
||||||
//Тело модуля
|
|
||||||
//-----------
|
|
||||||
|
|
||||||
//Хук для основной таблицы
|
|
||||||
const useCostJobs = () => {
|
|
||||||
//Собственное состояние - таблица данных
|
|
||||||
const [state, setState] = useState({
|
|
||||||
init: false,
|
|
||||||
loaded: false,
|
|
||||||
jobInfo: {},
|
|
||||||
haveNote: false,
|
|
||||||
coeff: "1.0"
|
|
||||||
});
|
|
||||||
|
|
||||||
//Подключение к контексту взаимодействия с сервером
|
|
||||||
const { executeStored } = useContext(BackEndСtx);
|
|
||||||
//Подключение к контексту навигации
|
|
||||||
const { getNavigationSearch } = useContext(NavigationCtx);
|
|
||||||
|
|
||||||
//При подключении компонента к странице
|
|
||||||
useEffect(() => {
|
|
||||||
const initJob = async fcJob => {
|
|
||||||
const data = await executeStored({
|
|
||||||
stored: "PKG_P8PANELS_MECHREC.FCJOBS_MP_INIT",
|
|
||||||
args: { NFCJOBS: parseInt(fcJob) },
|
|
||||||
respArg: "COUT",
|
|
||||||
attributeValueProcessor: (name, val) => (["NHAVE_NOTE"].includes(name) ? val == 1 : val)
|
|
||||||
});
|
|
||||||
setState(pv => ({
|
|
||||||
...pv,
|
|
||||||
init: true,
|
|
||||||
jobInfo: data.XFCJOBS ? data.XFCJOBS : {},
|
|
||||||
loaded: true
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
if (!state.init) {
|
|
||||||
//Считаем параметры, переданные из действия
|
|
||||||
const actionPrms = getNavigationSearch();
|
|
||||||
//Иницализируем сменное задание
|
|
||||||
initJob(actionPrms.NRN);
|
|
||||||
}
|
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return [state, setState];
|
|
||||||
};
|
|
||||||
|
|
||||||
//Хук для таблицы операций
|
|
||||||
const useCostJobsSpecs = task => {
|
|
||||||
//Собственное состояние - таблица данных
|
|
||||||
const [costJobsSpecs, setCostJobsSpecs] = useState({
|
|
||||||
task: null,
|
|
||||||
dataLoaded: false,
|
|
||||||
columnsDef: [],
|
|
||||||
orders: null,
|
|
||||||
rows: [],
|
|
||||||
selectedRow: {},
|
|
||||||
reload: true,
|
|
||||||
pageNumber: 1,
|
|
||||||
morePages: true
|
|
||||||
});
|
|
||||||
|
|
||||||
//Подключение к контексту взаимодействия с сервером
|
|
||||||
const { executeStored, SERV_DATA_TYPE_CLOB } = useContext(BackEndСtx);
|
|
||||||
|
|
||||||
//Выдача задания
|
|
||||||
const issueCostJobsSpecs = useCallback(
|
|
||||||
async prms => {
|
|
||||||
try {
|
|
||||||
await executeStored({
|
|
||||||
stored: "PKG_P8PANELS_MECHREC.FCJOBSSP_MP_ISSUE",
|
|
||||||
args: { NFCJOBS: prms.NFCJOBS, NCOEFF: parseFloat(prms.NCOEFF) }
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
throw new Error(e.message);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[executeStored]
|
|
||||||
);
|
|
||||||
|
|
||||||
//При необходимости обновить данные таблицы
|
|
||||||
useEffect(() => {
|
|
||||||
//Если изменилось сменное задание - обновляем состояние
|
|
||||||
if (costJobsSpecs.dataLoaded && costJobsSpecs.task !== task) {
|
|
||||||
setCostJobsSpecs(pv => ({
|
|
||||||
...pv,
|
|
||||||
dataLoaded: false,
|
|
||||||
columnsDef: [],
|
|
||||||
orders: null,
|
|
||||||
rows: [],
|
|
||||||
selectedRow: {},
|
|
||||||
reload: true,
|
|
||||||
pageNumber: 1,
|
|
||||||
morePages: true
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
//Если необходимо перезагрузить
|
|
||||||
if (costJobsSpecs.reload && task) {
|
|
||||||
const loadData = async () => {
|
|
||||||
const data = await executeStored({
|
|
||||||
stored: "PKG_P8PANELS_MECHREC.FCJOBSSP_MP_DG_GET",
|
|
||||||
args: {
|
|
||||||
NFCJOBS: task,
|
|
||||||
NPAGE_NUMBER: costJobsSpecs.pageNumber,
|
|
||||||
NPAGE_SIZE: DATA_GRID_PAGE_SIZE,
|
|
||||||
CORDERS: { VALUE: object2Base64XML(costJobsSpecs.orders, { arrayNodeName: "orders" }), SDATA_TYPE: SERV_DATA_TYPE_CLOB },
|
|
||||||
NINCLUDE_DEF: costJobsSpecs.dataLoaded ? 0 : 1
|
|
||||||
},
|
|
||||||
respArg: "COUT",
|
|
||||||
attributeValueProcessor: (name, val) =>
|
|
||||||
name === "NSELECT" ? val === 1 : name === "SWORKERS_LIST" ? (val ? val.split(",").map(Number) : []) : val
|
|
||||||
});
|
|
||||||
setCostJobsSpecs(pv => ({
|
|
||||||
...pv,
|
|
||||||
...data.XDATA_GRID,
|
|
||||||
task: task,
|
|
||||||
columnsDef: data.XDATA_GRID.columnsDef ? [...data.XDATA_GRID.columnsDef] : pv.columnsDef,
|
|
||||||
rows: pv.pageNumber == 1 ? [...(data.XDATA_GRID.rows || [])] : [...pv.rows, ...(data.XDATA_GRID.rows || [])],
|
|
||||||
dataLoaded: true,
|
|
||||||
reload: false,
|
|
||||||
morePages: (data.XDATA_GRID.rows || []).length >= DATA_GRID_PAGE_SIZE
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
loadData();
|
|
||||||
}
|
|
||||||
}, [
|
|
||||||
SERV_DATA_TYPE_CLOB,
|
|
||||||
costJobsSpecs.dataLoaded,
|
|
||||||
costJobsSpecs.orders,
|
|
||||||
costJobsSpecs.pageNumber,
|
|
||||||
costJobsSpecs.reload,
|
|
||||||
costJobsSpecs.task,
|
|
||||||
executeStored,
|
|
||||||
task
|
|
||||||
]);
|
|
||||||
|
|
||||||
return [costJobsSpecs, setCostJobsSpecs, issueCostJobsSpecs];
|
|
||||||
};
|
|
||||||
|
|
||||||
//Хук для рабочих
|
|
||||||
const useCostJobsWorkers = task => {
|
|
||||||
//Собственное состояние - таблица данных
|
|
||||||
const [costJobsWorkers, setCostJobsWorkers] = useState({
|
|
||||||
task: null,
|
|
||||||
dataLoaded: false,
|
|
||||||
columnsDef: [],
|
|
||||||
orders: null,
|
|
||||||
rows: [],
|
|
||||||
selectedRows: [],
|
|
||||||
reload: true,
|
|
||||||
pageNumber: 1,
|
|
||||||
morePages: true
|
|
||||||
});
|
|
||||||
|
|
||||||
//Подключение к контексту взаимодействия с сервером
|
|
||||||
const { executeStored, SERV_DATA_TYPE_CLOB } = useContext(BackEndСtx);
|
|
||||||
|
|
||||||
//Включение рабочего в строку сменного задания
|
|
||||||
const includeWorker = useCallback(
|
|
||||||
async prms => {
|
|
||||||
try {
|
|
||||||
await executeStored({
|
|
||||||
stored: "PKG_P8PANELS_MECHREC.FCJOBSSP_MP_INC_PERFORM",
|
|
||||||
args: {
|
|
||||||
NFCJOBSSP: prms.NFCJOBSSP,
|
|
||||||
SPERFORM_LIST: {
|
|
||||||
VALUE: Array.isArray(prms.SELECTED_WORKERS) ? prms.SELECTED_WORKERS.join(";") : prms.SELECTED_WORKERS,
|
|
||||||
SDATA_TYPE: SERV_DATA_TYPE_CLOB
|
|
||||||
},
|
|
||||||
NQUANT_PLAN: prms.NQUANT_PLAN
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
throw new Error(e.message);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[SERV_DATA_TYPE_CLOB, executeStored]
|
|
||||||
);
|
|
||||||
|
|
||||||
//Исключение рабочего из строки сменного задания
|
|
||||||
const excludeWorker = useCallback(
|
|
||||||
async prms => {
|
|
||||||
try {
|
|
||||||
await executeStored({
|
|
||||||
stored: "PKG_P8PANELS_MECHREC.FCJOBSSP_MP_EXC_PERFORM",
|
|
||||||
args: { NFCJOBSSP: prms.NFCJOBSSP }
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
throw new Error(e.message);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[executeStored]
|
|
||||||
);
|
|
||||||
|
|
||||||
//При необходимости обновить данные таблицы
|
|
||||||
useEffect(() => {
|
|
||||||
//Если изменилось сменное задание - обновляем состояние
|
|
||||||
if (costJobsWorkers.dataLoaded && costJobsWorkers.task !== task) {
|
|
||||||
setCostJobsWorkers(pv => ({
|
|
||||||
...pv,
|
|
||||||
dataLoaded: false,
|
|
||||||
columnsDef: [],
|
|
||||||
orders: null,
|
|
||||||
rows: [],
|
|
||||||
selectedRows: [],
|
|
||||||
reload: true,
|
|
||||||
pageNumber: 1,
|
|
||||||
morePages: true
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
//Если необходимо перезагрузить
|
|
||||||
if (costJobsWorkers.reload && task) {
|
|
||||||
const loadData = async () => {
|
|
||||||
const data = await executeStored({
|
|
||||||
stored: "PKG_P8PANELS_MECHREC.WORKERS_MP_DG_GET",
|
|
||||||
args: {
|
|
||||||
NFCJOBS: task,
|
|
||||||
NPAGE_NUMBER: costJobsWorkers.pageNumber,
|
|
||||||
NPAGE_SIZE: DATA_GRID_PAGE_SIZE,
|
|
||||||
CORDERS: { VALUE: object2Base64XML(costJobsWorkers.orders, { arrayNodeName: "orders" }), SDATA_TYPE: SERV_DATA_TYPE_CLOB },
|
|
||||||
NINCLUDE_DEF: costJobsWorkers.dataLoaded ? 0 : 1
|
|
||||||
},
|
|
||||||
respArg: "COUT",
|
|
||||||
attributeValueProcessor: (name, val) => (["NSELECT"].includes(name) ? val === 1 : val)
|
|
||||||
});
|
|
||||||
setCostJobsWorkers(pv => ({
|
|
||||||
...pv,
|
|
||||||
...data.XDATA_GRID,
|
|
||||||
task: task,
|
|
||||||
columnsDef: data.XDATA_GRID.columnsDef ? [...data.XDATA_GRID.columnsDef] : pv.columnsDef,
|
|
||||||
rows: pv.pageNumber == 1 ? [...(data.XDATA_GRID.rows || [])] : [...pv.rows, ...(data.XDATA_GRID.rows || [])],
|
|
||||||
dataLoaded: true,
|
|
||||||
reload: false,
|
|
||||||
morePages: (data.XDATA_GRID.rows || []).length >= DATA_GRID_PAGE_SIZE
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
loadData();
|
|
||||||
}
|
|
||||||
}, [
|
|
||||||
SERV_DATA_TYPE_CLOB,
|
|
||||||
costJobsWorkers.dataLoaded,
|
|
||||||
costJobsWorkers.orders,
|
|
||||||
costJobsWorkers.pageNumber,
|
|
||||||
costJobsWorkers.reload,
|
|
||||||
costJobsWorkers.task,
|
|
||||||
executeStored,
|
|
||||||
task
|
|
||||||
]);
|
|
||||||
|
|
||||||
return [costJobsWorkers, setCostJobsWorkers, includeWorker, excludeWorker];
|
|
||||||
};
|
|
||||||
|
|
||||||
export { useCostJobs, useCostJobsSpecs, useCostJobsWorkers };
|
|
@ -1,16 +0,0 @@
|
|||||||
/*
|
|
||||||
Парус 8 - Панели мониторинга - ПУП - Выдача сменного задания на участок
|
|
||||||
Панель мониторинга: Точка входа
|
|
||||||
*/
|
|
||||||
|
|
||||||
//---------------------
|
|
||||||
//Подключение библиотек
|
|
||||||
//---------------------
|
|
||||||
|
|
||||||
import { MechRecCostJobs } from "./mech_rec_cost_jobs_manage_mp"; //Корневая панель выдачи сменного задания на участок
|
|
||||||
|
|
||||||
//----------------
|
|
||||||
//Интерфейс модуля
|
|
||||||
//----------------
|
|
||||||
|
|
||||||
export const RootClass = MechRecCostJobs;
|
|
@ -1,483 +0,0 @@
|
|||||||
/*
|
|
||||||
Парус 8 - Панели мониторинга - ПУП - Выдача сменного задания на участок
|
|
||||||
Панель мониторинга: Корневая панель выдачи сменного задания на участок
|
|
||||||
*/
|
|
||||||
|
|
||||||
//---------------------
|
|
||||||
//Подключение библиотек
|
|
||||||
//---------------------
|
|
||||||
|
|
||||||
import React, { useState } from "react"; //Классы React
|
|
||||||
import { Grid, Box, Typography, Checkbox, Icon, Stack, Button, Tooltip, TextField } from "@mui/material"; //Интерфейсные элементы
|
|
||||||
import { APP_BAR_HEIGHT } from "../../components/p8p_app_workspace"; //Заголовок страницы
|
|
||||||
import { APP_STYLES } from "../../../app.styles"; //Типовые стили
|
|
||||||
import { P8PDataGrid, P8P_DATA_GRID_SIZE, P8P_DATA_GRID_MORE_HEIGHT } from "../../components/p8p_data_grid"; //Таблица данных
|
|
||||||
import { P8P_DATA_GRID_CONFIG_PROPS } from "../../config_wrapper"; //Подключение компонентов к настройкам приложения
|
|
||||||
import { useCostJobs, useCostJobsSpecs, useCostJobsWorkers } from "./hooks"; //Вспомогательные хуки
|
|
||||||
import { CostJobsSpecsInclude } from "./worker_include_dialog"; //Компонент диалога включения в задание
|
|
||||||
import { hasValue } from "../../core/utils"; //Вспомогательные функции
|
|
||||||
|
|
||||||
//---------
|
|
||||||
//Константы
|
|
||||||
//---------
|
|
||||||
|
|
||||||
//Мнемокод раздела операций
|
|
||||||
const UNIT_COST_JOBS_SPECS = "CostJobsSpecs";
|
|
||||||
|
|
||||||
//Мнемокод раздела исполнений должности
|
|
||||||
const UNIT_WORKERS = "ClientPostPerform";
|
|
||||||
|
|
||||||
//Высота основного заголовка
|
|
||||||
const MAIN_HEADER_HEIGHT = "35px";
|
|
||||||
|
|
||||||
//Высота подзаголовка
|
|
||||||
const SUB_HEADER_HEIGHT = "35px";
|
|
||||||
|
|
||||||
//Высота заголовка таблицы
|
|
||||||
const TABLE_HEADER_HEIGHT = "35px";
|
|
||||||
|
|
||||||
//Высота панели кнопок таблицы
|
|
||||||
const TABLE_BUTTONS_HEIGHT = "35px";
|
|
||||||
|
|
||||||
//Отступ таблицы
|
|
||||||
const TABLE_PADDING_TOP = "15px";
|
|
||||||
|
|
||||||
//Формат для коэффициент выполнения норм
|
|
||||||
const issueCoeffFormat = /^(?!.*\..*\.)[0-9]{0,3}(\.[0-9]{0,1})?$/;
|
|
||||||
|
|
||||||
//Стили
|
|
||||||
const STYLES = {
|
|
||||||
MAIN_HEADER: { height: MAIN_HEADER_HEIGHT, overflow: "hidden" },
|
|
||||||
SUB_HEADER: { height: SUB_HEADER_HEIGHT, overflow: "hidden" },
|
|
||||||
CONTAINER: { textAlign: "center" },
|
|
||||||
TABLE: { paddingTop: TABLE_PADDING_TOP },
|
|
||||||
TABLE_HEADER: { height: TABLE_HEADER_HEIGHT, overflow: "hidden" },
|
|
||||||
TABLE_BUTTONS: { display: "flex", justifyContent: "flex-end", height: TABLE_BUTTONS_HEIGHT, overflow: "hidden", alignItems: "flex-end" },
|
|
||||||
DATA_GRID_CONTAINER: morePages => ({
|
|
||||||
height: `calc(100vh - ${APP_BAR_HEIGHT} - ${MAIN_HEADER_HEIGHT} - ${SUB_HEADER_HEIGHT} - ${TABLE_HEADER_HEIGHT} - ${TABLE_BUTTONS_HEIGHT} - ${TABLE_PADDING_TOP} - 32px - ${
|
|
||||||
morePages ? P8P_DATA_GRID_MORE_HEIGHT : "0px"
|
|
||||||
})`,
|
|
||||||
...APP_STYLES.SCROLL
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
//Цвета
|
|
||||||
const colors = {
|
|
||||||
LINKED: "#bce0de",
|
|
||||||
UNAVAILABLE: "#949494",
|
|
||||||
WITH_WORKER: "#82df83"
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------------
|
|
||||||
//Вспомогательные функции и компоненты
|
|
||||||
//------------------------------------
|
|
||||||
|
|
||||||
//Проверка правильности значения коэффициент выполнения норм
|
|
||||||
const isValidIssueCoeff = value => {
|
|
||||||
return issueCoeffFormat.test(value);
|
|
||||||
};
|
|
||||||
|
|
||||||
//Форматирование значения ячейки
|
|
||||||
const dataCellRender = ({ row, columnDef, handleSelectChange, sUnit, selectedWorkerRows = [], selectedJobSpec }) => {
|
|
||||||
//Стиль
|
|
||||||
let cellStyle = {};
|
|
||||||
//Если это рабочие
|
|
||||||
if (sUnit === UNIT_WORKERS) {
|
|
||||||
//Признак недоступности
|
|
||||||
let disabled = true;
|
|
||||||
//Если в выбранной строке смены указан исполнитель факт
|
|
||||||
if (selectedJobSpec.NPERFORM_FACT) {
|
|
||||||
//Если это текущей исполнитель
|
|
||||||
if (selectedJobSpec.SWORKERS_LIST.includes(row["NRN"])) {
|
|
||||||
//Подсвечиваем строку рабочего
|
|
||||||
cellStyle = { backgroundColor: colors.LINKED };
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//Если выбрана строка смены
|
|
||||||
if (selectedJobSpec.NRN) {
|
|
||||||
//Если текущий рабочий может принять задание
|
|
||||||
if (row["NLOADING"] < 100) {
|
|
||||||
//Подсвечиваем строку рабочего
|
|
||||||
cellStyle = { backgroundColor: colors.LINKED };
|
|
||||||
disabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//Если уже выбрано достаточное количество рабочих и текущий рабочий не отмечен
|
|
||||||
if (selectedJobSpec.NRESOURCE_NUMB === selectedWorkerRows.length && !selectedWorkerRows.includes(row["NRN"])) {
|
|
||||||
//Устанавливаем признак недоступности
|
|
||||||
disabled = true;
|
|
||||||
}
|
|
||||||
//Если загрузка рабочего больше 100
|
|
||||||
if (row["NLOADING"] >= 100) {
|
|
||||||
//Если поле не поле выбора
|
|
||||||
if (columnDef.name !== "NSELECT") {
|
|
||||||
//Указываем, что рабочее место недоступно
|
|
||||||
cellStyle = { ...cellStyle, color: colors.UNAVAILABLE };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//Для колонки выбора
|
|
||||||
if (columnDef.name === "NSELECT") {
|
|
||||||
return {
|
|
||||||
cellStyle,
|
|
||||||
data: (
|
|
||||||
<Box sx={STYLES.CONTAINER}>
|
|
||||||
<Checkbox
|
|
||||||
disabled={disabled}
|
|
||||||
checked={selectedWorkerRows.includes(row["NRN"])}
|
|
||||||
onChange={() => handleSelectChange({ NRN: row["NRN"], SUNIT: sUnit, BFULL_LOADED: row["NLOADING"] >= 100 })}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
//Отформатированная колонка
|
|
||||||
return {
|
|
||||||
cellStyle,
|
|
||||||
data: row[columnDef.name]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
//Если это сменное задание
|
|
||||||
if (sUnit === UNIT_COST_JOBS_SPECS) {
|
|
||||||
//Если указан исполнитель факт
|
|
||||||
if (row["NPERFORM_FACT"]) {
|
|
||||||
//Подсвечиваем сменное задание зеленым
|
|
||||||
cellStyle = { ...cellStyle, backgroundColor: colors.WITH_WORKER };
|
|
||||||
}
|
|
||||||
//Для колонки выбора
|
|
||||||
if (columnDef.name === "NSELECT") {
|
|
||||||
return {
|
|
||||||
cellStyle,
|
|
||||||
data: (
|
|
||||||
<Box sx={STYLES.CONTAINER}>
|
|
||||||
<Checkbox
|
|
||||||
disabled={row["DBEG_FACT"] ? true : false}
|
|
||||||
checked={row["NRN"] === selectedJobSpec.NRN}
|
|
||||||
onChange={() =>
|
|
||||||
handleSelectChange({
|
|
||||||
NRN: row["NRN"],
|
|
||||||
SUNIT: sUnit,
|
|
||||||
NPERFORM_FACT: row["NPERFORM_FACT"],
|
|
||||||
NRESOURCE_NUMB: row["NRESOURCE_NUMB"],
|
|
||||||
NQUANT_PLAN: row["NQUANT_PLAN"],
|
|
||||||
SWORKERS_LIST: row["SWORKERS_LIST"]
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
//Отформатированная колонка
|
|
||||||
return {
|
|
||||||
cellStyle,
|
|
||||||
data: row[columnDef.name]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
//Необрабатываемый раздел
|
|
||||||
return {
|
|
||||||
data: row[columnDef.name]
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
//Генерация представления ячейки заголовка группы
|
|
||||||
export const headCellRender = ({ columnDef }) => {
|
|
||||||
if (columnDef.name === "NSELECT") {
|
|
||||||
return {
|
|
||||||
stackStyle: { padding: "2px", justifyContent: "space-around" },
|
|
||||||
data: <Icon>done</Icon>
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
stackStyle: { padding: "2px" },
|
|
||||||
data: columnDef.caption
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//-----------
|
|
||||||
//Тело модуля
|
|
||||||
//-----------
|
|
||||||
|
|
||||||
//Корневая панель выдачи сменного задания на участок
|
|
||||||
const MechRecCostJobs = () => {
|
|
||||||
//Состояние диалога включения в задание
|
|
||||||
const [showInclude, setShowInclude] = useState(false);
|
|
||||||
|
|
||||||
//Состояние информации о сменном задании
|
|
||||||
const [state, setState] = useCostJobs();
|
|
||||||
|
|
||||||
//Состояние таблицы сменных заданий
|
|
||||||
const [costJobsSpecs, setCostJobsSpecs, issueCostJobsSpecs] = useCostJobsSpecs(state.jobInfo.NRN);
|
|
||||||
|
|
||||||
//Состояние таблицы рабочих
|
|
||||||
const [costJobsWorkers, setCostJobsWorkers, includeWorker, excludeWorker] = useCostJobsWorkers(state.jobInfo.NRN);
|
|
||||||
|
|
||||||
//При изменении состояния сортировки операций
|
|
||||||
const handleCostJobsSpecOrderChanged = ({ orders }) => setCostJobsSpecs(pv => ({ ...pv, orders: [...orders], pageNumber: 1, reload: true }));
|
|
||||||
|
|
||||||
//При изменении количества отображаемых страниц операций
|
|
||||||
const handleCostJobsSpecPagesCountChanged = () => setCostJobsSpecs(pv => ({ ...pv, pageNumber: pv.pageNumber + 1, reload: true }));
|
|
||||||
|
|
||||||
//При изменении состояния сортировки рабочих
|
|
||||||
const handleCostJobsWorkersOrderChanged = ({ orders }) => setCostJobsWorkers(pv => ({ ...pv, orders: [...orders], pageNumber: 1, reload: true }));
|
|
||||||
|
|
||||||
//При изменении количества отображаемых страниц рабочих
|
|
||||||
const handleCostJobsWorkersPagesCountChanged = () => setCostJobsWorkers(pv => ({ ...pv, pageNumber: pv.pageNumber + 1, reload: true }));
|
|
||||||
|
|
||||||
//При исключении рабочих из строки сменного задания
|
|
||||||
const handleCostJobsSpecExcludeWorker = () => {
|
|
||||||
//Делаем асинхронно, чтобы при ошибке ничего не обновлять
|
|
||||||
const excludeAsync = async () => {
|
|
||||||
//Исключаем рабочего из строки сменного задания
|
|
||||||
try {
|
|
||||||
await excludeWorker({
|
|
||||||
NFCJOBSSP: costJobsSpecs.selectedRow.NRN
|
|
||||||
});
|
|
||||||
//Необходимо обновить данные
|
|
||||||
setCostJobsSpecs(pv => ({ ...pv, selectedRow: {}, pageNumber: 1, reload: true }));
|
|
||||||
setCostJobsWorkers(pv => ({ ...pv, selectedRows: [], pageNumber: 1, reload: true }));
|
|
||||||
} catch (e) {
|
|
||||||
throw new Error(e.message);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
//Исключаем рабочего асинхронно
|
|
||||||
excludeAsync();
|
|
||||||
};
|
|
||||||
|
|
||||||
//Выдача задания операции
|
|
||||||
const handleCostJobsSpecIssue = () => {
|
|
||||||
//Делаем асинхронно, чтобы при ошибке ничего не обновлять
|
|
||||||
const issueAsync = async () => {
|
|
||||||
//Включаем рабочих в операции
|
|
||||||
try {
|
|
||||||
await issueCostJobsSpecs({ NFCJOBS: state.jobInfo.NRN, NCOEFF: state.coeff });
|
|
||||||
//Необходимо обновить данные
|
|
||||||
setCostJobsSpecs(pv => ({ ...pv, selectedRow: {}, pageNumber: 1, reload: true }));
|
|
||||||
setCostJobsWorkers(pv => ({ ...pv, selectedRows: [], pageNumber: 1, reload: true }));
|
|
||||||
} catch (e) {
|
|
||||||
throw new Error(e.message);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
//Выдаем задание асинхронно
|
|
||||||
issueAsync();
|
|
||||||
};
|
|
||||||
|
|
||||||
//При изменение состояния выбора
|
|
||||||
const handleSelectChange = prms => {
|
|
||||||
//Выбранный элемент
|
|
||||||
let selectedRow = null;
|
|
||||||
//Буфер для выбранных рабочих
|
|
||||||
let selectedWorkers = [];
|
|
||||||
//Индекс рабочего в списке выбранных
|
|
||||||
let workerIndex = null;
|
|
||||||
//Исходим от раздела
|
|
||||||
switch (prms.SUNIT) {
|
|
||||||
//Сменное задание
|
|
||||||
case UNIT_COST_JOBS_SPECS:
|
|
||||||
//Определяем это новое отмеченное сменное задание или сброс старого
|
|
||||||
selectedRow = costJobsSpecs.selectedRow.NRN ? (costJobsSpecs.selectedRow.NRN === prms.NRN ? null : prms.NRN) : prms.NRN;
|
|
||||||
//Актуализируем строки
|
|
||||||
setCostJobsSpecs(pv => ({
|
|
||||||
...pv,
|
|
||||||
selectedRow: selectedRow
|
|
||||||
? {
|
|
||||||
NRN: selectedRow,
|
|
||||||
NPERFORM_FACT: prms.NPERFORM_FACT,
|
|
||||||
NRESOURCE_NUMB: prms.NRESOURCE_NUMB,
|
|
||||||
NQUANT_PLAN: prms.NQUANT_PLAN,
|
|
||||||
SWORKERS_LIST: prms.SWORKERS_LIST
|
|
||||||
}
|
|
||||||
: { NRN: null, NPERFORM_FACT: null, NRESOURCE_NUMB: null, NQUANT_PLAN: null, SWORKERS_LIST: [] }
|
|
||||||
}));
|
|
||||||
//Выходим
|
|
||||||
break;
|
|
||||||
//Рабочие центры
|
|
||||||
case UNIT_WORKERS:
|
|
||||||
//Инициализируем рабочими центрами
|
|
||||||
selectedWorkers = costJobsWorkers.selectedRows || [];
|
|
||||||
//Определяем индекс элемента в массиве
|
|
||||||
workerIndex = selectedWorkers.indexOf(prms.NRN);
|
|
||||||
//Если такого рег. номера нет в списке - добавляем, иначе удаляем
|
|
||||||
workerIndex > -1 ? selectedWorkers.splice(workerIndex, 1) : selectedWorkers.push(prms.NRN);
|
|
||||||
//Актуализируем строки
|
|
||||||
setCostJobsWorkers(pv => ({ ...pv, selectedRows: selectedWorkers }));
|
|
||||||
//Выходим
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//При открытии/закрытии диалога добавления
|
|
||||||
const handleShowIncludeChange = needShow => setShowInclude(needShow);
|
|
||||||
|
|
||||||
//При изменении коэффициент выполнения норм
|
|
||||||
const handleIssueCoeffChange = e => {
|
|
||||||
isValidIssueCoeff(e.target.value) ? setState(pv => ({ ...pv, coeff: e.target.value })) : null;
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Box p={2}>
|
|
||||||
{state.loaded ? (
|
|
||||||
<Box sx={STYLES.CONTAINER}>
|
|
||||||
<Typography
|
|
||||||
sx={STYLES.MAIN_HEADER}
|
|
||||||
variant={"h6"}
|
|
||||||
>{`Сменное задание №${state.jobInfo.SDOC_NUMB} на ${state.jobInfo.SPERIOD}`}</Typography>
|
|
||||||
<Typography sx={STYLES.SUB_HEADER} variant={"h6"}>{`${state.jobInfo.SSUBDIV}`}</Typography>
|
|
||||||
<Box sx={STYLES.CONTAINER}>
|
|
||||||
<Grid container spacing={2}>
|
|
||||||
<Grid item sx={STYLES.CONTAINER} xs={6}>
|
|
||||||
<Typography sx={STYLES.TABLE_HEADER} variant={"h6"} color={"text.secondary"}>
|
|
||||||
Сменное задание
|
|
||||||
</Typography>
|
|
||||||
{costJobsWorkers.dataLoaded ? (
|
|
||||||
<>
|
|
||||||
<Box sx={STYLES.TABLE_BUTTONS}>
|
|
||||||
<Stack direction={"row"} spacing={1}>
|
|
||||||
<Tooltip
|
|
||||||
title={
|
|
||||||
state.jobInfo.NHAVE_NOTE
|
|
||||||
? "Сменное задание имеет строку с примечанием"
|
|
||||||
: "Коэффициент выполнения норм"
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<TextField
|
|
||||||
name="editIssueValue"
|
|
||||||
variant="outlined"
|
|
||||||
sx={{ width: "68px" }}
|
|
||||||
inputProps={{ sx: { padding: "4.2px 14px" } }}
|
|
||||||
size="small"
|
|
||||||
value={state.coeff}
|
|
||||||
onChange={handleIssueCoeffChange}
|
|
||||||
disabled={state.jobInfo.NHAVE_NOTE}
|
|
||||||
/>
|
|
||||||
</Tooltip>
|
|
||||||
<Tooltip
|
|
||||||
title={
|
|
||||||
state.jobInfo.NHAVE_NOTE
|
|
||||||
? "Сменное задание имеет строку с примечанием"
|
|
||||||
: !hasValue(state.coeff)
|
|
||||||
? "Не указано значение коэффициент выполнения норм"
|
|
||||||
: null
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Box>
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
size="small"
|
|
||||||
disabled={state.jobInfo.NHAVE_NOTE || !hasValue(state.coeff)}
|
|
||||||
onClick={handleCostJobsSpecIssue}
|
|
||||||
>
|
|
||||||
Выдать задания
|
|
||||||
</Button>
|
|
||||||
</Box>
|
|
||||||
</Tooltip>
|
|
||||||
</Stack>
|
|
||||||
</Box>
|
|
||||||
<Box sx={STYLES.TABLE}>
|
|
||||||
<P8PDataGrid
|
|
||||||
{...P8P_DATA_GRID_CONFIG_PROPS}
|
|
||||||
containerComponentProps={{ sx: STYLES.DATA_GRID_CONTAINER(costJobsSpecs.morePages), elevation: 1 }}
|
|
||||||
columnsDef={costJobsSpecs.columnsDef}
|
|
||||||
rows={costJobsSpecs.rows}
|
|
||||||
size={P8P_DATA_GRID_SIZE.SMALL}
|
|
||||||
morePages={costJobsSpecs.morePages}
|
|
||||||
reloading={costJobsSpecs.reload}
|
|
||||||
onOrderChanged={handleCostJobsSpecOrderChanged}
|
|
||||||
onPagesCountChanged={handleCostJobsSpecPagesCountChanged}
|
|
||||||
dataCellRender={prms =>
|
|
||||||
dataCellRender({
|
|
||||||
...prms,
|
|
||||||
handleSelectChange,
|
|
||||||
sUnit: UNIT_COST_JOBS_SPECS,
|
|
||||||
selectedJobSpec: costJobsSpecs.selectedRow
|
|
||||||
})
|
|
||||||
}
|
|
||||||
headCellRender={prms => headCellRender({ ...prms })}
|
|
||||||
fixedHeader={true}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
</>
|
|
||||||
) : null}
|
|
||||||
</Grid>
|
|
||||||
<Grid item sx={STYLES.CONTAINER} xs={6}>
|
|
||||||
<Typography sx={STYLES.TABLE_HEADER} variant={"h6"} color={"text.secondary"}>
|
|
||||||
Рабочие
|
|
||||||
</Typography>
|
|
||||||
{costJobsWorkers.dataLoaded ? (
|
|
||||||
<>
|
|
||||||
<Box sx={STYLES.TABLE_BUTTONS}>
|
|
||||||
<Stack direction={"row"} spacing={1}>
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
size="small"
|
|
||||||
disabled={!(costJobsSpecs.selectedRow.NRESOURCE_NUMB === costJobsWorkers.selectedRows.length)}
|
|
||||||
onClick={() => handleShowIncludeChange(true)}
|
|
||||||
>
|
|
||||||
Включить в задание
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
size="small"
|
|
||||||
disabled={!costJobsSpecs.selectedRow.NRN || !costJobsSpecs.selectedRow.NPERFORM_FACT}
|
|
||||||
onClick={handleCostJobsSpecExcludeWorker}
|
|
||||||
>
|
|
||||||
Исключить из задания
|
|
||||||
</Button>
|
|
||||||
</Stack>
|
|
||||||
</Box>
|
|
||||||
<Box sx={STYLES.TABLE}>
|
|
||||||
<P8PDataGrid
|
|
||||||
{...P8P_DATA_GRID_CONFIG_PROPS}
|
|
||||||
containerComponentProps={{ sx: STYLES.DATA_GRID_CONTAINER(costJobsWorkers.morePages), elevation: 1 }}
|
|
||||||
columnsDef={costJobsWorkers.columnsDef}
|
|
||||||
rows={costJobsWorkers.rows}
|
|
||||||
size={P8P_DATA_GRID_SIZE.SMALL}
|
|
||||||
morePages={costJobsWorkers.morePages}
|
|
||||||
reloading={costJobsWorkers.reload}
|
|
||||||
onOrderChanged={handleCostJobsWorkersOrderChanged}
|
|
||||||
onPagesCountChanged={handleCostJobsWorkersPagesCountChanged}
|
|
||||||
dataCellRender={prms =>
|
|
||||||
dataCellRender({
|
|
||||||
...prms,
|
|
||||||
handleSelectChange,
|
|
||||||
sUnit: UNIT_WORKERS,
|
|
||||||
selectedWorkerRows: costJobsWorkers.selectedRows,
|
|
||||||
selectedJobSpec: costJobsSpecs.selectedRow
|
|
||||||
})
|
|
||||||
}
|
|
||||||
headCellRender={prms => headCellRender({ ...prms })}
|
|
||||||
fixedHeader={true}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
</>
|
|
||||||
) : null}
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
) : null}
|
|
||||||
{showInclude ? (
|
|
||||||
<CostJobsSpecsInclude
|
|
||||||
includePrms={{
|
|
||||||
NFCJOBSSP: costJobsSpecs.selectedRow.NRN,
|
|
||||||
SELECTED_WORKERS: costJobsWorkers.selectedRows,
|
|
||||||
NQUANT_PLAN: costJobsSpecs.selectedRow.NQUANT_PLAN
|
|
||||||
}}
|
|
||||||
setShowInclude={setShowInclude}
|
|
||||||
setCostJobsSpecs={setCostJobsSpecs}
|
|
||||||
setCostJobsWorkers={setCostJobsWorkers}
|
|
||||||
includeWorker={includeWorker}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
//----------------
|
|
||||||
//Интерфейс модуля
|
|
||||||
//----------------
|
|
||||||
|
|
||||||
export { MechRecCostJobs };
|
|
@ -1,103 +0,0 @@
|
|||||||
/*
|
|
||||||
Парус 8 - Панели мониторинга - ПУП - Выдача сменного задания на участок
|
|
||||||
Панель мониторинга: Диалог включения рабочего в сменное задание
|
|
||||||
*/
|
|
||||||
|
|
||||||
//---------------------
|
|
||||||
//Подключение библиотек
|
|
||||||
//---------------------
|
|
||||||
|
|
||||||
import React, { useState } from "react"; //Классы React
|
|
||||||
import PropTypes from "prop-types"; //Контроль свойств компонента
|
|
||||||
import { Box, Button, Dialog, DialogTitle, DialogContent, TextField, DialogActions } from "@mui/material"; //Интерфейсные элементы
|
|
||||||
import { BUTTONS } from "../../../app.text"; //Текстовые ресурсы
|
|
||||||
|
|
||||||
//-----------
|
|
||||||
//Тело модуля
|
|
||||||
//-----------
|
|
||||||
|
|
||||||
//Диалог включения рабочего в сменное задание
|
|
||||||
const CostJobsSpecsInclude = ({ includePrms, setShowInclude, setCostJobsSpecs, setCostJobsWorkers, includeWorker }) => {
|
|
||||||
//Собственное состояние - Значение приоритета
|
|
||||||
const [state, setState] = useState(includePrms.NQUANT_PLAN);
|
|
||||||
|
|
||||||
//При закрытии включения рабочего
|
|
||||||
const handlePriorEditClose = () => setShowInclude(false);
|
|
||||||
|
|
||||||
//При включении рабочего в строку сменного задания
|
|
||||||
const costJobsSpecIncludeCostEquipment = () => {
|
|
||||||
//Делаем асинхронно, чтобы при ошибке ничего не обновлять
|
|
||||||
const includeAsync = async () => {
|
|
||||||
//Включаем рабочего в строку сменного задания
|
|
||||||
try {
|
|
||||||
await includeWorker({
|
|
||||||
NFCJOBSSP: includePrms.NFCJOBSSP,
|
|
||||||
SELECTED_WORKERS: includePrms.SELECTED_WORKERS,
|
|
||||||
NQUANT_PLAN: state
|
|
||||||
});
|
|
||||||
//Необходимо обновить все данные
|
|
||||||
setCostJobsSpecs(pv => ({ ...pv, selectedRow: {}, pageNumber: 1, reload: true }));
|
|
||||||
setCostJobsWorkers(pv => ({ ...pv, selectedRows: [], pageNumber: 1, reload: true }));
|
|
||||||
handlePriorEditClose();
|
|
||||||
} catch (e) {
|
|
||||||
throw new Error(e.message);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
//Включаем рабочего асинхронно
|
|
||||||
includeAsync();
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Dialog open onClose={() => handlePriorEditClose()}>
|
|
||||||
<DialogTitle>Включить в задание</DialogTitle>
|
|
||||||
<DialogContent>
|
|
||||||
<Box>
|
|
||||||
<TextField
|
|
||||||
name="editInculdeValue"
|
|
||||||
label="Количество"
|
|
||||||
variant="standard"
|
|
||||||
fullWidth
|
|
||||||
InputProps={{
|
|
||||||
type: "number",
|
|
||||||
inputProps: {
|
|
||||||
max: includePrms.NQUANT_PLAN,
|
|
||||||
min: 0
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
value={state}
|
|
||||||
onChange={event => {
|
|
||||||
var value = parseInt(event.target.value, 10);
|
|
||||||
if (value > includePrms.NQUANT_PLAN) {
|
|
||||||
value = includePrms.NQUANT_PLAN;
|
|
||||||
}
|
|
||||||
if (value < 0) {
|
|
||||||
value = 0;
|
|
||||||
}
|
|
||||||
setState(value);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<Box></Box>
|
|
||||||
</Box>
|
|
||||||
</DialogContent>
|
|
||||||
<DialogActions>
|
|
||||||
<Button onClick={costJobsSpecIncludeCostEquipment}>{BUTTONS.OK}</Button>
|
|
||||||
<Button onClick={() => handlePriorEditClose(null)}>{BUTTONS.CANCEL}</Button>
|
|
||||||
</DialogActions>
|
|
||||||
</Dialog>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
//Контроль свойств - Диалог включения рабочего в сменное задание
|
|
||||||
CostJobsSpecsInclude.propTypes = {
|
|
||||||
includePrms: PropTypes.object.isRequired,
|
|
||||||
setShowInclude: PropTypes.func.isRequired,
|
|
||||||
setCostJobsSpecs: PropTypes.func.isRequired,
|
|
||||||
setCostJobsWorkers: PropTypes.func.isRequired,
|
|
||||||
includeWorker: PropTypes.func.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
//----------------
|
|
||||||
//Интерфейс модуля
|
|
||||||
//----------------
|
|
||||||
|
|
||||||
export { CostJobsSpecsInclude };
|
|
File diff suppressed because it is too large
Load Diff
@ -120,16 +120,6 @@
|
|||||||
icon="psychology"
|
icon="psychology"
|
||||||
showInPanelsList="true"
|
showInPanelsList="true"
|
||||||
preview="./img/mech_rec_cost_jobs_manage.jpg"/>
|
preview="./img/mech_rec_cost_jobs_manage.jpg"/>
|
||||||
<Panel
|
|
||||||
name="MechRecCostJobsManageMP"
|
|
||||||
group="Планирование и учёт в дискретном производстве"
|
|
||||||
caption="Выдача сменного задания на участок"
|
|
||||||
desc="Управление составом сменных заданий трудового ресурса"
|
|
||||||
url="mech_rec_cost_jobs_manage_mp"
|
|
||||||
path="mech_rec_cost_jobs_manage_mp"
|
|
||||||
icon=""
|
|
||||||
showInPanelsList="false"
|
|
||||||
preview=""/>
|
|
||||||
<Panel
|
<Panel
|
||||||
name="MechRecDeptCostJobs"
|
name="MechRecDeptCostJobs"
|
||||||
group="Планирование и учёт в дискретном производстве"
|
group="Планирование и учёт в дискретном производстве"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user