diff --git a/app/panels/mech_rec_cost_jobs_manage_mp/hooks.js b/app/panels/mech_rec_cost_jobs_manage_mp/hooks.js
new file mode 100644
index 0000000..5d319a7
--- /dev/null
+++ b/app/panels/mech_rec_cost_jobs_manage_mp/hooks.js
@@ -0,0 +1,279 @@
+/*
+ Парус 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 };
diff --git a/app/panels/mech_rec_cost_jobs_manage_mp/index.js b/app/panels/mech_rec_cost_jobs_manage_mp/index.js
new file mode 100644
index 0000000..704e3e2
--- /dev/null
+++ b/app/panels/mech_rec_cost_jobs_manage_mp/index.js
@@ -0,0 +1,16 @@
+/*
+ Парус 8 - Панели мониторинга - ПУП - Выдача сменного задания на участок
+ Панель мониторинга: Точка входа
+*/
+
+//---------------------
+//Подключение библиотек
+//---------------------
+
+import { MechRecCostJobs } from "./mech_rec_cost_jobs_manage_mp"; //Корневая панель выдачи сменного задания на участок
+
+//----------------
+//Интерфейс модуля
+//----------------
+
+export const RootClass = MechRecCostJobs;
diff --git a/app/panels/mech_rec_cost_jobs_manage_mp/mech_rec_cost_jobs_manage_mp.js b/app/panels/mech_rec_cost_jobs_manage_mp/mech_rec_cost_jobs_manage_mp.js
new file mode 100644
index 0000000..806da82
--- /dev/null
+++ b/app/panels/mech_rec_cost_jobs_manage_mp/mech_rec_cost_jobs_manage_mp.js
@@ -0,0 +1,483 @@
+/*
+ Парус 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: (
+
+ handleSelectChange({ NRN: row["NRN"], SUNIT: sUnit, BFULL_LOADED: row["NLOADING"] >= 100 })}
+ />
+
+ )
+ };
+ }
+ //Отформатированная колонка
+ 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: (
+
+
+ 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"]
+ })
+ }
+ />
+
+ )
+ };
+ }
+ //Отформатированная колонка
+ 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: done
+ };
+ } 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 (
+
+ {state.loaded ? (
+
+ {`Сменное задание №${state.jobInfo.SDOC_NUMB} на ${state.jobInfo.SPERIOD}`}
+ {`${state.jobInfo.SSUBDIV}`}
+
+
+
+
+ Сменное задание
+
+ {costJobsWorkers.dataLoaded ? (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ dataCellRender({
+ ...prms,
+ handleSelectChange,
+ sUnit: UNIT_COST_JOBS_SPECS,
+ selectedJobSpec: costJobsSpecs.selectedRow
+ })
+ }
+ headCellRender={prms => headCellRender({ ...prms })}
+ fixedHeader={true}
+ />
+
+ >
+ ) : null}
+
+
+
+ Рабочие
+
+ {costJobsWorkers.dataLoaded ? (
+ <>
+
+
+
+
+
+
+
+
+ dataCellRender({
+ ...prms,
+ handleSelectChange,
+ sUnit: UNIT_WORKERS,
+ selectedWorkerRows: costJobsWorkers.selectedRows,
+ selectedJobSpec: costJobsSpecs.selectedRow
+ })
+ }
+ headCellRender={prms => headCellRender({ ...prms })}
+ fixedHeader={true}
+ />
+
+ >
+ ) : null}
+
+
+
+
+ ) : null}
+ {showInclude ? (
+
+ ) : null}
+
+ );
+};
+
+//----------------
+//Интерфейс модуля
+//----------------
+
+export { MechRecCostJobs };
diff --git a/app/panels/mech_rec_cost_jobs_manage_mp/worker_include_dialog.js b/app/panels/mech_rec_cost_jobs_manage_mp/worker_include_dialog.js
new file mode 100644
index 0000000..2fef5f2
--- /dev/null
+++ b/app/panels/mech_rec_cost_jobs_manage_mp/worker_include_dialog.js
@@ -0,0 +1,103 @@
+/*
+ Парус 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 (
+
+ );
+};
+
+//Контроль свойств - Диалог включения рабочего в сменное задание
+CostJobsSpecsInclude.propTypes = {
+ includePrms: PropTypes.object.isRequired,
+ setShowInclude: PropTypes.func.isRequired,
+ setCostJobsSpecs: PropTypes.func.isRequired,
+ setCostJobsWorkers: PropTypes.func.isRequired,
+ includeWorker: PropTypes.func.isRequired
+};
+
+//----------------
+//Интерфейс модуля
+//----------------
+
+export { CostJobsSpecsInclude };
diff --git a/db/PKG_P8PANELS_MECHREC.pck b/db/PKG_P8PANELS_MECHREC.pck
index ce4dcf8..e9d53be 100644
--- a/db/PKG_P8PANELS_MECHREC.pck
+++ b/db/PKG_P8PANELS_MECHREC.pck
@@ -279,6 +279,56 @@ create or replace package PKG_P8PANELS_MECHREC as
NFCPRODPLANSP in number, -- Рег. номер строки плана
COUT out clob -- Сериализованная таблица данных
);
+
+ /* Выдать задания сменного задания */
+ procedure FCJOBSSP_MP_ISSUE
+ (
+ NFCJOBS in number, -- Рег. номер сменного задания
+ NCOEFF in number := 1.1 -- Коэффициент выполнения норм
+ );
+
+ /* Исключение исполнителя из операции сменного задания */
+ procedure FCJOBSSP_MP_EXC_PERFORM
+ (
+ NFCJOBSSP in number -- Рег. номер строки сменного задания
+ );
+
+ /* Включение исполнителя в строку сменного задания */
+ procedure FCJOBSSP_MP_INC_PERFORM
+ (
+ NFCJOBSSP in number, -- Рег. номер строки сменного задания
+ SPERFORM_LIST in clob, -- Список отмеченных исполнителей (разделитель - ";")
+ NQUANT_PLAN in number -- Включаемое количество
+ );
+
+ /* Получение спецификации сменного задания */
+ procedure FCJOBSSP_MP_DG_GET
+ (
+ NFCJOBS in number, -- Рег. номер сменного задания
+ NPAGE_NUMBER in number, -- Номер страницы (игнорируется при NPAGE_SIZE=0)
+ NPAGE_SIZE in number, -- Количество записей на странице (0 - все)
+ CORDERS in clob, -- Сортировки
+ NINCLUDE_DEF in number, -- Признак включения описания колонок таблицы в ответ
+ COUT out clob -- Сериализованная таблица данных
+ );
+
+ /* Получение рабочих подразделения */
+ procedure WORKERS_MP_DG_GET
+ (
+ NFCJOBS in number, -- Рег. номер сменного задания
+ NPAGE_NUMBER in number, -- Номер страницы (игнорируется при NPAGE_SIZE=0)
+ NPAGE_SIZE in number, -- Количество записей на странице (0 - все)
+ CORDERS in clob, -- Сортировки
+ NINCLUDE_DEF in number, -- Признак включения описания колонок таблицы в ответ
+ COUT out clob -- Сериализованная таблица данных
+ );
+
+ /* Инициализация записей раздела "Сменные задания" */
+ procedure FCJOBS_MP_INIT
+ (
+ NFCJOBS in number, -- Рег. номер записи сменного задания
+ COUT out clob -- Информация о записи сменного задания
+ );
end PKG_P8PANELS_MECHREC;
/
@@ -6607,6 +6657,1153 @@ create or replace package body PKG_P8PANELS_MECHREC as
PKG_STATE.DIAGNOSTICS_STACKED();
P_EXCEPTION(0, PKG_STATE.SQL_ERRM());
end FCPRODCMP_DETAILS_GET;
+
+ /*
+ Процедуры панели "Выдача сменного задания на участок"
+ */
+
+ /* Выдать задания сменного задания */
+ procedure FCJOBSSP_MP_ISSUE
+ (
+ NFCJOBS in number, -- Рег. номер сменного задания
+ NCOEFF in number := 1.1 -- Коэффициент выполнения норм
+ )
+ is
+ NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса
+ NDICMUNTS PKG_STD.TREF; -- Рег. номер ед. изм. дня
+ DSTART_DATE PKG_STD.TLDATE; -- Дата начала строки плана
+ DEND_DATE PKG_STD.TLDATE; -- Дата окончания строки плана
+ begin
+ /* Если сменное задание не указано */
+ if (NFCJOBS is null) then
+ P_EXCEPTION(0, 'Сменное задание не определено.');
+ end if;
+ /* Считываем единицу измерения минут */
+ FIND_DICMUNTS_CODE(NFLAG_SMART => 0,
+ NFLAG_OPTION => 0,
+ NCOMPANY => NCOMPANY,
+ SMEAS_MNEMO => SDICMUNTS_DAY,
+ NRN => NDICMUNTS);
+ /* Отбираем строки с пустым исполнителем факт */
+ for REC in (select T.RN
+ from FCJOBSSP T
+ where T.PRN = NFCJOBS
+ and T.PERFORM_FACT is null)
+ loop
+ /* Удаляем строку */
+ P_FCJOBSSP_BASE_DELETE(NRN => REC.RN, NCOMPANY => NCOMPANY);
+ end loop;
+ /* Цикл по исполнителям строк */
+ for PF in (select T.PERFORM_FACT from FCJOBSSP T where T.PRN = NFCJOBS group by T.PERFORM_FACT)
+ loop
+ /* Цикл по строкам с текущим исполнителем */
+ for REC in (select TMP.*,
+ DECODE(B.RN, null, TMP.DDOC_DATE, TMP.DDOC_DATE + B.BEG_TIME) DSTART,
+ F_DICMUNTS_BASE_RECALC_QUANT(0, TMP.COMPANY, TMP.MUNIT, TMP.LABOUR_PLAN, NDICMUNTS) NLABOUR,
+ ROWNUM RNUM
+ from (select T.*,
+ J.DOCDATE DDOC_DATE,
+ COALESCE(T.TBOPERMODESP, J.TBOPERMODESP) NTBOPERMODESP
+ from FCJOBS J,
+ FCJOBSSP T
+ where J.RN = NFCJOBS
+ and T.PRN = J.RN
+ and T.PERFORM_FACT = PF.PERFORM_FACT
+ order by T.PRIOR_PARTY asc) TMP,
+ TBOPERMODESP B
+ where B.RN = TMP.NTBOPERMODESP)
+ loop
+ /* Если это первая строка - устанавливаем по смене */
+ if (REC.RNUM = 1) then
+ DSTART_DATE := REC.DSTART;
+ DEND_DATE := DSTART_DATE + REC.NLABOUR / NCOEFF;
+ else
+ DSTART_DATE := DEND_DATE;
+ DEND_DATE := DSTART_DATE + REC.NLABOUR / NCOEFF;
+ end if;
+ /* Обновляем запись строки */
+ P_FCJOBSSP_BASE_UPDATE(NRN => REC.RN,
+ NCOMPANY => REC.COMPANY,
+ SNUMB => REC.NUMB,
+ NTBOPERMODESP => REC.TBOPERMODESP,
+ SBARCODE => REC.BARCODE,
+ NFACEACC => REC.FACEACC,
+ NMATRES => REC.MATRES,
+ NNOMCLASSIF => REC.NOMCLASSIF,
+ NARTICLE => REC.ARTICLE,
+ NFCROUTSHTSP => REC.FCROUTSHTSP,
+ SOPER_NUMB => REC.OPER_NUMB,
+ NOPER_TPS => REC.OPER_TPS,
+ SOPER_UK => REC.OPER_UK,
+ NSIGN_CONTRL => REC.SIGN_CONTRL,
+ NMANPOWER => REC.MANPOWER,
+ NCATEGORY => REC.CATEGORY,
+ DBEG_PLAN => DSTART_DATE,
+ DEND_PLAN => DEND_DATE,
+ DBEG_FACT => REC.BEG_FACT,
+ DEND_FACT => REC.END_FACT,
+ NQUANT_PLAN => REC.QUANT_PLAN,
+ NQUANT_FACT => REC.QUANT_FACT,
+ NNORM => REC.NORM,
+ NT_SHT_FACT => REC.T_SHT_FACT,
+ NT_PZ_PLAN => REC.T_PZ_PLAN,
+ NT_PZ_FACT => REC.T_PZ_FACT,
+ NT_VSP_PLAN => REC.T_VSP_PLAN,
+ NT_VSP_FACT => REC.T_VSP_FACT,
+ NT_O_PLAN => REC.T_O_PLAN,
+ NT_O_FACT => REC.T_O_FACT,
+ NNORM_TYPE => REC.NORM_TYPE,
+ NSIGN_P_R => REC.SIGN_P_R,
+ NLABOUR_PLAN => REC.LABOUR_PLAN,
+ NLABOUR_FACT => REC.LABOUR_FACT,
+ NCOST_PLAN => REC.COST_PLAN,
+ NCOST_FACT => REC.COST_FACT,
+ NCOST_FOR => REC.COST_FOR,
+ NCURNAMES => REC.CURNAMES,
+ NPERFORM_PLAN => REC.PERFORM_PLAN,
+ NPERFORM_FACT => REC.PERFORM_FACT,
+ NSTAFFGRP_PLAN => REC.STAFFGRP_PLAN,
+ NSTAFFGRP_FACT => REC.STAFFGRP_FACT,
+ NEQUIP_PLAN => REC.EQUIP_PLAN,
+ NEQUIP_FACT => REC.EQUIP_FACT,
+ NLOSTTYPE => REC.LOSTTYPE,
+ NLOSTDEFL => REC.LOSTDEFL,
+ NFOREMAN => REC.FOREMAN,
+ NINSPECTOR => REC.INSPECTOR,
+ DOTK_DATE => REC.OTK_DATE,
+ NSUBDIV => REC.SUBDIV,
+ NEQCONFIG => REC.EQCONFIG,
+ SNOTE => 'Задание выдано ' || TO_CHAR(sysdate, 'dd.mm.yyyy hh24:mi:ss'),
+ NMUNIT => REC.MUNIT);
+ end loop;
+ end loop;
+ end FCJOBSSP_MP_ISSUE;
+
+ /* Исключение исполнителя из операции сменного задания */
+ procedure FCJOBSSP_MP_EXC_PERFORM
+ (
+ NFCJOBSSP in number -- Рег. номер строки сменного задания
+ )
+ is
+ NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса
+ RFCJOBSSP FCJOBSSP%rowtype; -- Запись строки сменного задания
+ begin
+ /* Если рег. номер строки не указан */
+ if (NFCJOBSSP is null) then
+ P_EXCEPTION(0, 'Строка сменного задания не определена.');
+ end if;
+ /* Считываем запись строки сменного задания */
+ RFCJOBSSP := UTL_FCJOBSSP_GET(NCOMPANY => NCOMPANY, NFCJOBSSP => NFCJOBSSP);
+ /* Если дата начала факт указана */
+ if (RFCJOBSSP.BEG_FACT is not null) then
+ P_EXCEPTION(0, 'Указанная строка сменного задания исполняется.');
+ end if;
+ /* Исключаем исполнителя */
+ P_FCJOBSSP_BASE_UPDATE(NRN => RFCJOBSSP.RN,
+ NCOMPANY => RFCJOBSSP.COMPANY,
+ SNUMB => RFCJOBSSP.NUMB,
+ NTBOPERMODESP => RFCJOBSSP.TBOPERMODESP,
+ SBARCODE => RFCJOBSSP.BARCODE,
+ NFACEACC => RFCJOBSSP.FACEACC,
+ NMATRES => RFCJOBSSP.MATRES,
+ NNOMCLASSIF => RFCJOBSSP.NOMCLASSIF,
+ NARTICLE => RFCJOBSSP.ARTICLE,
+ NFCROUTSHTSP => RFCJOBSSP.FCROUTSHTSP,
+ SOPER_NUMB => RFCJOBSSP.OPER_NUMB,
+ NOPER_TPS => RFCJOBSSP.OPER_TPS,
+ SOPER_UK => RFCJOBSSP.OPER_UK,
+ NSIGN_CONTRL => RFCJOBSSP.SIGN_CONTRL,
+ NMANPOWER => RFCJOBSSP.MANPOWER,
+ NCATEGORY => RFCJOBSSP.CATEGORY,
+ DBEG_PLAN => RFCJOBSSP.BEG_PLAN,
+ DEND_PLAN => RFCJOBSSP.END_PLAN,
+ DBEG_FACT => RFCJOBSSP.BEG_FACT,
+ DEND_FACT => RFCJOBSSP.END_FACT,
+ NQUANT_PLAN => RFCJOBSSP.QUANT_PLAN,
+ NQUANT_FACT => RFCJOBSSP.QUANT_FACT,
+ NNORM => RFCJOBSSP.NORM,
+ NT_SHT_FACT => RFCJOBSSP.T_SHT_FACT,
+ NT_PZ_PLAN => RFCJOBSSP.T_PZ_PLAN,
+ NT_PZ_FACT => RFCJOBSSP.T_PZ_FACT,
+ NT_VSP_PLAN => RFCJOBSSP.T_VSP_PLAN,
+ NT_VSP_FACT => RFCJOBSSP.T_VSP_FACT,
+ NT_O_PLAN => RFCJOBSSP.T_O_PLAN,
+ NT_O_FACT => RFCJOBSSP.T_O_FACT,
+ NNORM_TYPE => RFCJOBSSP.NORM_TYPE,
+ NSIGN_P_R => RFCJOBSSP.SIGN_P_R,
+ NLABOUR_PLAN => RFCJOBSSP.LABOUR_PLAN,
+ NLABOUR_FACT => RFCJOBSSP.LABOUR_FACT,
+ NCOST_PLAN => RFCJOBSSP.COST_PLAN,
+ NCOST_FACT => RFCJOBSSP.COST_FACT,
+ NCOST_FOR => RFCJOBSSP.COST_FOR,
+ NCURNAMES => RFCJOBSSP.CURNAMES,
+ NPERFORM_PLAN => RFCJOBSSP.PERFORM_PLAN,
+ NPERFORM_FACT => null,
+ NSTAFFGRP_PLAN => RFCJOBSSP.STAFFGRP_PLAN,
+ NSTAFFGRP_FACT => RFCJOBSSP.STAFFGRP_FACT,
+ NEQUIP_PLAN => RFCJOBSSP.EQUIP_PLAN,
+ NEQUIP_FACT => RFCJOBSSP.EQUIP_FACT,
+ NLOSTTYPE => RFCJOBSSP.LOSTTYPE,
+ NLOSTDEFL => RFCJOBSSP.LOSTDEFL,
+ NFOREMAN => RFCJOBSSP.FOREMAN,
+ NINSPECTOR => RFCJOBSSP.INSPECTOR,
+ DOTK_DATE => RFCJOBSSP.OTK_DATE,
+ NSUBDIV => RFCJOBSSP.SUBDIV,
+ NEQCONFIG => RFCJOBSSP.EQCONFIG,
+ SNOTE => RFCJOBSSP.NOTE,
+ NMUNIT => RFCJOBSSP.MUNIT);
+ /* Очищаем строки дополнительных ресурсов */
+ for REC in (select T.* from FCJOBSSPAR T where T.PRN = RFCJOBSSP.RN)
+ loop
+ /* Очищаем исполнителя дополнительного ресурса */
+ P_FCJOBSSPAR_BASE_UPDATE(NRN => REC.RN,
+ NCOMPANY => REC.COMPANY,
+ NROUTSHTSPAR => REC.ROUTSHTSPAR,
+ NEQUIPMENT => REC.EQUIPMENT,
+ NMANPOWER => REC.MANPOWER,
+ NCATEGORY => REC.CATEGORY,
+ NNORM => REC.NORM,
+ NNORM_TYPE => REC.NORM_TYPE,
+ NSIGN_P_R => REC.SIGN_P_R,
+ NLABOUR_PLAN => REC.LABOUR_PLAN,
+ NLABOUR_FACT => REC.LABOUR_FACT,
+ NCOST_PLAN => REC.COST_PLAN,
+ NCOST_FACT => REC.COST_FACT,
+ NCOST_FOR => REC.COST_FOR,
+ NCURNAMES => REC.CURNAMES,
+ NPERFORM_PLAN => REC.PERFORM_PLAN,
+ NPERFORM_FACT => null,
+ NMUNIT => REC.MUNIT,
+ NPROCTYPE => REC.PROCTYPE);
+ end loop;
+ end FCJOBSSP_MP_EXC_PERFORM;
+
+ /* Включение исполнителя в строку сменного задания */
+ procedure FCJOBSSP_MP_INC_PERFORM
+ (
+ NFCJOBSSP in number, -- Рег. номер строки сменного задания
+ SPERFORM_LIST in clob, -- Список отмеченных исполнителей (разделитель - ";")
+ NQUANT_PLAN in number -- Включаемое количество
+ )
+ is
+ NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса
+ NQUANT_REMN PKG_STD.TLNUMBER; -- Остаток количества
+ RFCJOBSSP FCJOBSSP%rowtype; -- Запись строки сменного задания
+ NNEW_FCJOBSSP PKG_STD.TREF; -- Рег. номер новой строки сменного задания
+ NNEW_FCJOBSSPAR PKG_STD.TREF; -- Рег. номер нового дополнительного ресурса строки сменного задания
+ NROUTLST PKG_STD.TREF; -- Рег. номер связанного МЛ
+ NROUTLSTSP PKG_STD.TREF; -- Рег. номер связанной строки МЛ
+ NCLNPSPFM PKG_STD.TREF; -- Рег. номер исполнения должности
+
+ /* Проверка наличия состава оборудования */
+ procedure CLNPSPFM_EXISTS
+ (
+ NCLNPSPFM in number, -- Рег. номер исполнения должности
+ NCOMPANY in number -- Рег. номер организации
+ )
+ is
+ NEXISTS PKG_STD.TNUMBER; -- Буфер
+ begin
+ /* Проверяем наличие оборудования */
+ begin
+ select T.RN
+ into NEXISTS
+ from CLNPSPFM T
+ where T.RN = NCLNPSPFM
+ and T.COMPANY = NCOMPANY;
+ exception
+ when others then
+ P_EXCEPTION(0, 'Рабочее место не найдено.');
+ end;
+ end CLNPSPFM_EXISTS;
+
+ /* Пересчет "Трудоемкость план" строки сменного задания */
+ procedure LABOUR_PLAN_RECALC
+ (
+ RFCJOBSSP in out FCJOBSSP%rowtype, -- Запись строки сменного задания
+ NQUANT_PLAN in number -- Количество план
+ )
+ is
+ begin
+ /* Если не установлен признак "То план" */
+ if ((RFCJOBSSP.T_O_PLAN is null) or ((RFCJOBSSP.T_O_PLAN is not null) and (RFCJOBSSP.T_O_PLAN = 0))) then
+ /* Если установлен признак "На партию выпуска" */
+ if (RFCJOBSSP.SIGN_P_R = 1) then
+ RFCJOBSSP.LABOUR_PLAN := RFCJOBSSP.NORM;
+ else
+ RFCJOBSSP.LABOUR_PLAN := RFCJOBSSP.NORM * NQUANT_PLAN;
+ end if;
+ else
+ /* Если установлен признак "На партию выпуска" */
+ if (RFCJOBSSP.SIGN_P_R = 1) then
+ RFCJOBSSP.LABOUR_PLAN := RFCJOBSSP.T_O_PLAN + COALESCE(RFCJOBSSP.T_PZ_PLAN, 0) +
+ COALESCE(RFCJOBSSP.T_VSP_PLAN, 0);
+ else
+ RFCJOBSSP.LABOUR_PLAN := RFCJOBSSP.T_O_PLAN * NQUANT_PLAN + COALESCE(RFCJOBSSP.T_PZ_PLAN, 0) +
+ COALESCE(RFCJOBSSP.T_VSP_PLAN, 0);
+ end if;
+ end if;
+ end LABOUR_PLAN_RECALC;
+ begin
+ /* Если включаемое количество меньше 0 или пустое */
+ if ((NQUANT_PLAN is null) or ((NQUANT_PLAN is not null) and (NQUANT_PLAN <= 0))) then
+ P_EXCEPTION(0, 'Невозможно включить указанное количество.');
+ end if;
+ /* Если рег. номер строки не указан */
+ if (NFCJOBSSP is null) then
+ P_EXCEPTION(0, 'Строка сменного задания не определена.');
+ end if;
+ /* Считываем запись строки сменного задания */
+ RFCJOBSSP := UTL_FCJOBSSP_GET(NCOMPANY => NCOMPANY, NFCJOBSSP => NFCJOBSSP);
+ /* Если дата начала факт указана */
+ if (RFCJOBSSP.BEG_FACT is not null) then
+ P_EXCEPTION(0, 'Указанная строка сменного задания исполняется.');
+ end if;
+ /* Если включаемое количество больше текущего */
+ if (NQUANT_PLAN > RFCJOBSSP.QUANT_PLAN) then
+ P_EXCEPTION(0,
+ 'Указанное количество превышает текущее "Количество план" строки.');
+ end if;
+ /* Если список исполнителей пуст */
+ if (SPERFORM_LIST is null) then
+ P_EXCEPTION(0, 'Список исполнителей пуст.');
+ end if;
+ /* Рассчитываем остаточное количество */
+ NQUANT_REMN := RFCJOBSSP.QUANT_PLAN - NQUANT_PLAN;
+ /* Пересчитываем "Количество план" */
+ LABOUR_PLAN_RECALC(RFCJOBSSP => RFCJOBSSP, NQUANT_PLAN => NQUANT_PLAN);
+ /* Обходим исполнителей */
+ for I in 1 .. STRCNT(source => SPERFORM_LIST, DELIMETER => ';')
+ loop
+ /* Считываем рег. номер исполнения должности */
+ NCLNPSPFM := TO_NUMBER(STRTOK(source => SPERFORM_LIST, DELIMETER => ';', ITEM => I));
+ /* Проверяем наличие исполнения должности */
+ CLNPSPFM_EXISTS(NCLNPSPFM => NCLNPSPFM, NCOMPANY => NCOMPANY);
+ /* Если это первый отмеченный */
+ if (I = 1) then
+ /* Включаем исполнителя */
+ P_FCJOBSSP_BASE_UPDATE(NRN => RFCJOBSSP.RN,
+ NCOMPANY => RFCJOBSSP.COMPANY,
+ SNUMB => RFCJOBSSP.NUMB,
+ NTBOPERMODESP => RFCJOBSSP.TBOPERMODESP,
+ SBARCODE => RFCJOBSSP.BARCODE,
+ NFACEACC => RFCJOBSSP.FACEACC,
+ NMATRES => RFCJOBSSP.MATRES,
+ NNOMCLASSIF => RFCJOBSSP.NOMCLASSIF,
+ NARTICLE => RFCJOBSSP.ARTICLE,
+ NFCROUTSHTSP => RFCJOBSSP.FCROUTSHTSP,
+ SOPER_NUMB => RFCJOBSSP.OPER_NUMB,
+ NOPER_TPS => RFCJOBSSP.OPER_TPS,
+ SOPER_UK => RFCJOBSSP.OPER_UK,
+ NSIGN_CONTRL => RFCJOBSSP.SIGN_CONTRL,
+ NMANPOWER => RFCJOBSSP.MANPOWER,
+ NCATEGORY => RFCJOBSSP.CATEGORY,
+ DBEG_PLAN => RFCJOBSSP.BEG_PLAN,
+ DEND_PLAN => RFCJOBSSP.END_PLAN,
+ DBEG_FACT => RFCJOBSSP.BEG_FACT,
+ DEND_FACT => RFCJOBSSP.END_FACT,
+ NQUANT_PLAN => NQUANT_PLAN,
+ NQUANT_FACT => RFCJOBSSP.QUANT_FACT,
+ NNORM => RFCJOBSSP.NORM,
+ NT_SHT_FACT => RFCJOBSSP.T_SHT_FACT,
+ NT_PZ_PLAN => RFCJOBSSP.T_PZ_PLAN,
+ NT_PZ_FACT => RFCJOBSSP.T_PZ_FACT,
+ NT_VSP_PLAN => RFCJOBSSP.T_VSP_PLAN,
+ NT_VSP_FACT => RFCJOBSSP.T_VSP_FACT,
+ NT_O_PLAN => RFCJOBSSP.T_O_PLAN,
+ NT_O_FACT => RFCJOBSSP.T_O_FACT,
+ NNORM_TYPE => RFCJOBSSP.NORM_TYPE,
+ NSIGN_P_R => RFCJOBSSP.SIGN_P_R,
+ NLABOUR_PLAN => RFCJOBSSP.LABOUR_PLAN,
+ NLABOUR_FACT => RFCJOBSSP.LABOUR_FACT,
+ NCOST_PLAN => RFCJOBSSP.COST_PLAN,
+ NCOST_FACT => RFCJOBSSP.COST_FACT,
+ NCOST_FOR => RFCJOBSSP.COST_FOR,
+ NCURNAMES => RFCJOBSSP.CURNAMES,
+ NPERFORM_PLAN => RFCJOBSSP.PERFORM_PLAN,
+ NPERFORM_FACT => NCLNPSPFM,
+ NSTAFFGRP_PLAN => RFCJOBSSP.STAFFGRP_PLAN,
+ NSTAFFGRP_FACT => RFCJOBSSP.STAFFGRP_FACT,
+ NEQUIP_PLAN => RFCJOBSSP.EQUIP_PLAN,
+ NEQUIP_FACT => RFCJOBSSP.EQUIP_FACT,
+ NLOSTTYPE => RFCJOBSSP.LOSTTYPE,
+ NLOSTDEFL => RFCJOBSSP.LOSTDEFL,
+ NFOREMAN => RFCJOBSSP.FOREMAN,
+ NINSPECTOR => RFCJOBSSP.INSPECTOR,
+ DOTK_DATE => RFCJOBSSP.OTK_DATE,
+ NSUBDIV => RFCJOBSSP.SUBDIV,
+ NEQCONFIG => RFCJOBSSP.EQCONFIG,
+ SNOTE => RFCJOBSSP.NOTE,
+ NMUNIT => RFCJOBSSP.MUNIT);
+ /* Если есть остаток */
+ if (NQUANT_REMN <> 0) then
+ /* Обнуляем дату отработки */
+ RFCJOBSSP.WORK_DATE := null;
+ /* Получаем новый номер */
+ P_FCJOBSSP_GETNEXTNUMB(NCOMPANY => NCOMPANY, NPRN => RFCJOBSSP.PRN, SNUMB => RFCJOBSSP.NUMB);
+ /* Если штрихкод был указан */
+ if (RFCJOBSSP.BARCODE is not null) then
+ /* Получаем новый штрихкод */
+ P_FCJOBSSP_GET_BARCODE(NCOMPANY => NCOMPANY, NRN => RFCJOBSSP.RN, SBARCODE => RFCJOBSSP.BARCODE);
+ end if;
+ /* Пересчитываем "Количество план" */
+ LABOUR_PLAN_RECALC(RFCJOBSSP => RFCJOBSSP, NQUANT_PLAN => NQUANT_REMN);
+ /* Размножаем запись */
+ P_FCJOBSSP_BASE_INSERT(NCOMPANY => RFCJOBSSP.COMPANY,
+ NPRN => RFCJOBSSP.PRN,
+ SNUMB => RFCJOBSSP.NUMB,
+ NTBOPERMODESP => RFCJOBSSP.TBOPERMODESP,
+ SBARCODE => RFCJOBSSP.BARCODE,
+ NFACEACC => RFCJOBSSP.FACEACC,
+ NMATRES => RFCJOBSSP.MATRES,
+ NNOMCLASSIF => RFCJOBSSP.NOMCLASSIF,
+ NARTICLE => RFCJOBSSP.ARTICLE,
+ NFCROUTSHTSP => RFCJOBSSP.FCROUTSHTSP,
+ SOPER_NUMB => RFCJOBSSP.OPER_NUMB,
+ NOPER_TPS => RFCJOBSSP.OPER_TPS,
+ SOPER_UK => RFCJOBSSP.OPER_UK,
+ NSIGN_CONTRL => RFCJOBSSP.SIGN_CONTRL,
+ NMANPOWER => RFCJOBSSP.MANPOWER,
+ NCATEGORY => RFCJOBSSP.CATEGORY,
+ DBEG_PLAN => RFCJOBSSP.BEG_PLAN,
+ DEND_PLAN => RFCJOBSSP.END_PLAN,
+ DBEG_FACT => RFCJOBSSP.BEG_FACT,
+ DEND_FACT => RFCJOBSSP.END_FACT,
+ NQUANT_PLAN => NQUANT_REMN,
+ NQUANT_FACT => RFCJOBSSP.QUANT_FACT,
+ NNORM => RFCJOBSSP.NORM,
+ NT_SHT_FACT => RFCJOBSSP.T_SHT_FACT,
+ NT_PZ_PLAN => RFCJOBSSP.T_PZ_PLAN,
+ NT_PZ_FACT => RFCJOBSSP.T_PZ_FACT,
+ NT_VSP_PLAN => RFCJOBSSP.T_VSP_PLAN,
+ NT_VSP_FACT => RFCJOBSSP.T_VSP_FACT,
+ NT_O_PLAN => RFCJOBSSP.T_O_PLAN,
+ NT_O_FACT => RFCJOBSSP.T_O_FACT,
+ NNORM_TYPE => RFCJOBSSP.NORM_TYPE,
+ NSIGN_P_R => RFCJOBSSP.SIGN_P_R,
+ NLABOUR_PLAN => RFCJOBSSP.LABOUR_PLAN,
+ NLABOUR_FACT => RFCJOBSSP.LABOUR_FACT,
+ NCOST_PLAN => RFCJOBSSP.COST_PLAN,
+ NCOST_FACT => RFCJOBSSP.COST_FACT,
+ NCOST_FOR => RFCJOBSSP.COST_FOR,
+ NCURNAMES => RFCJOBSSP.CURNAMES,
+ NPERFORM_PLAN => RFCJOBSSP.PERFORM_PLAN,
+ NPERFORM_FACT => RFCJOBSSP.PERFORM_FACT,
+ NSTAFFGRP_PLAN => RFCJOBSSP.STAFFGRP_PLAN,
+ NSTAFFGRP_FACT => RFCJOBSSP.STAFFGRP_FACT,
+ NEQUIP_PLAN => RFCJOBSSP.EQUIP_PLAN,
+ NEQUIP_FACT => RFCJOBSSP.EQUIP_FACT,
+ NLOSTTYPE => RFCJOBSSP.LOSTTYPE,
+ NLOSTDEFL => RFCJOBSSP.LOSTDEFL,
+ NFOREMAN => RFCJOBSSP.FOREMAN,
+ NINSPECTOR => RFCJOBSSP.INSPECTOR,
+ DOTK_DATE => RFCJOBSSP.OTK_DATE,
+ NSUBDIV => RFCJOBSSP.SUBDIV,
+ NEQCONFIG => null,
+ NSIGN_AR => 1,
+ SNOTE => RFCJOBSSP.NOTE,
+ NMUNIT => RFCJOBSSP.MUNIT,
+ NPRIOR_ORDER => RFCJOBSSP.PRIOR_ORDER,
+ NPRIOR_PARTY => RFCJOBSSP.PRIOR_PARTY,
+ DEXEC_DATE => RFCJOBSSP.EXEC_DATE,
+ DREL_DATE => RFCJOBSSP.REL_DATE,
+ NRN => NNEW_FCJOBSSP);
+ /* Переносим дополнительные ресурсы */
+ for AR in (select T.* from FCJOBSSPAR T where T.PRN = RFCJOBSSP.RN)
+ loop
+ /* Добавляем дополнительный ресурс */
+ P_FCJOBSSPAR_BASE_INSERT(NCOMPANY => AR.COMPANY,
+ NPRN => NNEW_FCJOBSSP,
+ NROUTSHTSPAR => AR.ROUTSHTSPAR,
+ NEQUIPMENT => AR.EQUIPMENT,
+ NMANPOWER => AR.MANPOWER,
+ NCATEGORY => AR.CATEGORY,
+ NNORM => AR.NORM,
+ NNORM_TYPE => AR.NORM_TYPE,
+ NSIGN_P_R => AR.SIGN_P_R,
+ NLABOUR_PLAN => AR.LABOUR_PLAN,
+ NLABOUR_FACT => AR.LABOUR_FACT,
+ NCOST_PLAN => AR.COST_PLAN,
+ NCOST_FACT => AR.COST_FACT,
+ NCOST_FOR => AR.COST_FOR,
+ NCURNAMES => AR.CURNAMES,
+ NPERFORM_PLAN => AR.PERFORM_PLAN,
+ NPERFORM_FACT => null,
+ NMUNIT => AR.MUNIT,
+ NPROCTYPE => AR.PROCTYPE,
+ NRN => NNEW_FCJOBSSPAR);
+ end loop;
+ /* Связанные маршрутный лист и строка маршрутного листа */
+ NROUTLST := F_DOCLINKS_LINK_IN_DOC(SOUT_UNITCODE => 'CostJobsSpecs',
+ NOUT_DOCUMENT => RFCJOBSSP.RN,
+ SIN_UNITCODE => 'CostRouteLists');
+ NROUTLSTSP := F_DOCLINKS_LINK_IN_DOC(SOUT_UNITCODE => 'CostJobsSpecs',
+ NOUT_DOCUMENT => RFCJOBSSP.RN,
+ SIN_UNITCODE => 'CostRouteListsSpecs');
+ /* Связывание с новой строкой сменного задания */
+ if (NROUTLST is not null) and (NROUTLSTSP is not null) then
+ /* Создаем связь с заголовоком МЛ */
+ P_LINKSALL_LINK_DIRECT(NCOMPANY => NCOMPANY,
+ SIN_UNITCODE => 'CostRouteLists',
+ NIN_DOCUMENT => NROUTLST,
+ NIN_PRN_DOCUMENT => null,
+ DIN_IN_DATE => sysdate,
+ NIN_STATUS => 0,
+ SOUT_UNITCODE => 'CostJobsSpecs',
+ NOUT_DOCUMENT => NNEW_FCJOBSSP,
+ NOUT_PRN_DOCUMENT => RFCJOBSSP.PRN,
+ DOUT_IN_DATE => sysdate,
+ NOUT_STATUS => 0);
+ /* Создаем связь со спецификацией МЛ */
+ P_LINKSALL_LINK_DIRECT(NCOMPANY => NCOMPANY,
+ SIN_UNITCODE => 'CostRouteListsSpecs',
+ NIN_DOCUMENT => NROUTLSTSP,
+ NIN_PRN_DOCUMENT => NROUTLST,
+ DIN_IN_DATE => sysdate,
+ NIN_STATUS => 0,
+ SOUT_UNITCODE => 'CostJobsSpecs',
+ NOUT_DOCUMENT => NNEW_FCJOBSSP,
+ NOUT_PRN_DOCUMENT => RFCJOBSSP.PRN,
+ DOUT_IN_DATE => sysdate,
+ NOUT_STATUS => 0);
+ end if;
+ end if;
+ else
+ /* Отбираем строку дополнительного ресурса */
+ for AR in (select TMP.*
+ from (select ROWNUM as RNUM,
+ R.*
+ from (select T.* from FCJOBSSPAR T where T.PRN = RFCJOBSSP.RN order by T.RN asc) R) TMP
+ where TMP.RNUM = I - 1)
+ loop
+ /* Обновляем её */
+ P_FCJOBSSPAR_BASE_UPDATE(NRN => AR.RN,
+ NCOMPANY => AR.COMPANY,
+ NROUTSHTSPAR => AR.ROUTSHTSPAR,
+ NEQUIPMENT => AR.EQUIPMENT,
+ NMANPOWER => AR.MANPOWER,
+ NCATEGORY => AR.CATEGORY,
+ NNORM => AR.NORM,
+ NNORM_TYPE => AR.NORM_TYPE,
+ NSIGN_P_R => AR.SIGN_P_R,
+ NLABOUR_PLAN => AR.LABOUR_PLAN,
+ NLABOUR_FACT => AR.LABOUR_FACT,
+ NCOST_PLAN => AR.COST_PLAN,
+ NCOST_FACT => AR.COST_FACT,
+ NCOST_FOR => AR.COST_FOR,
+ NCURNAMES => AR.CURNAMES,
+ NPERFORM_PLAN => AR.PERFORM_PLAN,
+ NPERFORM_FACT => NCLNPSPFM,
+ NMUNIT => AR.MUNIT,
+ NPROCTYPE => AR.PROCTYPE);
+ end loop;
+ end if;
+ end loop;
+ end FCJOBSSP_MP_INC_PERFORM;
+
+ /* Получение спецификации сменного задания */
+ procedure FCJOBSSP_MP_DG_GET
+ (
+ NFCJOBS in number, -- Рег. номер сменного задания
+ NPAGE_NUMBER in number, -- Номер страницы (игнорируется при NPAGE_SIZE=0)
+ NPAGE_SIZE in number, -- Количество записей на странице (0 - все)
+ CORDERS in clob, -- Сортировки
+ NINCLUDE_DEF in number, -- Признак включения описания колонок таблицы в ответ
+ COUT out clob -- Сериализованная таблица данных
+ )
+ is
+ NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса
+ RO PKG_P8PANELS_VISUAL.TDG_ORDERS; -- Сортировки
+ RDG PKG_P8PANELS_VISUAL.TDG; -- Описание таблицы
+ RDG_ROW PKG_P8PANELS_VISUAL.TDG_ROW; -- Строка таблицы
+ NROW_FROM PKG_STD.TREF; -- Номер строки с
+ NROW_TO PKG_STD.TREF; -- Номер строки по
+ CSQL clob; -- Буфер для запроса
+ ICURSOR integer; -- Курсор для исполнения запроса
+ NVERSION PKG_STD.TREF; -- Версия контрагентов
+ SWORKERS_LIST PKG_STD.TSTRING; -- Список исполнителей строки сменного задания
+ NFCJOBSSP PKG_STD.TREF; -- Рег. номер строки сменного задания
+
+ /* Функция формирования списка всех исполнителей строки сменного задания */
+ function FCJOBSSP_WORKERS_LIST_GET
+ (
+ NFCJOBSSP in number -- Рег. номер строки сменного задания
+ ) return varchar2 -- Список исполнителей
+ is
+ SWORKERS_LIST PKG_STD.TSTRING; -- Список исполнителей
+ begin
+ /* Обходим исполнителей строки сменного задания */
+ for REC in (select T.PERFORM_FACT
+ from FCJOBSSP T
+ where T.RN = NFCJOBSSP
+ union
+ select S.PERFORM_FACT
+ from FCJOBSSPAR S
+ where S.PRN = NFCJOBSSP)
+ loop
+ SWORKERS_LIST := SWORKERS_LIST || REC.PERFORM_FACT || ',';
+ end loop;
+ /* Если есть исполнители */
+ SWORKERS_LIST := RTRIM(SWORKERS_LIST, ',');
+ /* Возвращаем список исполнителей */
+ return SWORKERS_LIST;
+ end FCJOBSSP_WORKERS_LIST_GET;
+ begin
+ /* Читем сортировки */
+ RO := PKG_P8PANELS_VISUAL.TDG_ORDERS_FROM_XML(CORDERS => CORDERS);
+ /* Считываем версию контрагентов */
+ FIND_VERSION_BY_COMPANY(NCOMPANY => NCOMPANY, SUNITCODE => 'AGNLIST', NVERSION => NVERSION);
+ /* Преобразуем номер и размер страницы в номер строк с и по */
+ PKG_P8PANELS_VISUAL.UTL_ROWS_LIMITS_CALC(NPAGE_NUMBER => NPAGE_NUMBER,
+ NPAGE_SIZE => NPAGE_SIZE,
+ NROW_FROM => NROW_FROM,
+ NROW_TO => NROW_TO);
+ /* Инициализируем таблицу данных */
+ RDG := PKG_P8PANELS_VISUAL.TDG_MAKE(BFIXED_HEADER => true, NFIXED_COLUMNS => 8);
+ /* Описываем колонки таблицы данных */
+ PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
+ SNAME => 'NRN',
+ SCAPTION => 'Рег. номер',
+ SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
+ BVISIBLE => false);
+ PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
+ SNAME => 'NSELECT',
+ SCAPTION => 'Выбран',
+ SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB);
+ PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
+ SNAME => 'SFCROUTLST',
+ SCAPTION => 'МЛ',
+ SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
+ BORDER => true);
+ PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
+ SNAME => 'SMATRES',
+ SCAPTION => 'ДСЕ',
+ SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
+ BORDER => true);
+ PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
+ SNAME => 'SOPER',
+ SCAPTION => 'Операция',
+ SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
+ BORDER => true);
+ PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
+ SNAME => 'SMANPOWER',
+ SCAPTION => 'Профессия',
+ SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR);
+ PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
+ SNAME => 'NQUANT_PLAN',
+ SCAPTION => 'Количество',
+ SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB);
+ PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
+ SNAME => 'NRESOURCE_NUMB',
+ SCAPTION => 'Численность',
+ SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB);
+ PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
+ SNAME => 'NLABOUR_PLAN',
+ SCAPTION => 'Трудоемкость',
+ SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB);
+ PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
+ SNAME => 'SFIO',
+ SCAPTION => 'ФИО',
+ SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR);
+ PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
+ SNAME => 'NPERFORM_FACT',
+ SCAPTION => 'Рег. номер исполнителя факт',
+ SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
+ BVISIBLE => false);
+ PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
+ SNAME => 'DBEG_FACT',
+ SCAPTION => 'Дата начала факт',
+ SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_DATE,
+ BVISIBLE => false);
+ PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
+ SNAME => 'SWORKERS_LIST',
+ SCAPTION => 'Список исполнителей',
+ SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
+ BVISIBLE => false);
+ /* Обходим данные */
+ begin
+ /* Добавляем подсказку совместимости */
+ CSQL := PKG_SQL_BUILD.COMPATIBLE(SSQL => CSQL);
+ /* Формируем запрос */
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => 'select *');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from (select D.*,');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.SQLROWNUM() || ' NROW');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from (select T.RN NRN,');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' (select ' || PKG_SQL_BUILD.SET_HINT(SHINT => 'INDEX(L I_DOCLINKS_OUT_DOCUMENT)'));
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' TRIM(D.DOCNUMB) || '' '' || to_char(D.DOCDATE, ''dd.mm.yyyy'')');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from DOCLINKS L,');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' FCROUTLST D');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' where L.OUT_DOCUMENT = T.RN');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and L.OUT_UNITCODE = ' || PKG_SQL_BUILD.WRAP_STR(SVALUE => 'CostJobsSpecs'));
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and L.IN_DOCUMENT = D.RN');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and L.IN_UNITCODE = ' || PKG_SQL_BUILD.WRAP_STR(SVALUE => 'CostRouteLists'));
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' ' || PKG_SQL_BUILD.ROWLIMIT(NLIMIT => 1, BAND => true) || ') SFCROUTLST,');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' MR.CODE || '' '' || MR."NAME" SMATRES,');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' TRIM(T.OPER_NUMB) || '' '' || ( select coalesce(O."NAME", T.OPER_UK) from FCOPERTYPES O where T.OPER_TPS = O.RN ) SOPER,');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' (select MP.CODE from FCMANPOWER MP where T.MANPOWER = MP.RN) SMANPOWER,');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' T.QUANT_PLAN NQUANT_PLAN,');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' COALESCE((select COUNT(SP.RN)');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from FCJOBSSPAR SP');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' where SP.PRN = T.RN), 0) + 1 NRESOURCE_NUMB,');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' T.LABOUR_PLAN NLABOUR_PLAN,');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' (select AG.AGNFAMILYNAME');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from CLNPSPFM C,');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' CLNPERSONS P,');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' AGNLIST AG');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' where C.RN = T.PERFORM_FACT');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and C.PERSRN = P.RN');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and P.PERS_AGENT = AG.RN) SFIO,');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' T.PERFORM_FACT NPERFORM_FACT,');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' T.BEG_FACT DBEG_FACT');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from FCJOBSSP T,');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' FCMATRESOURCE MR');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' where T.PRN = :NFCJOBS');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and T.COMPANY = :NCOMPANY');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and T.SIGN_CONTRL = ' || PKG_SQL_BUILD.WRAP_NUM(NVALUE => 0));
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and MR.RN = T.MATRES');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' %ORDER_BY%) D) F');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' where F.NROW between :NROW_FROM and :NROW_TO');
+ /* Если сортировки не указаны */
+ if (CORDERS is not null) then
+ /* Учтём сортировки */
+ PKG_P8PANELS_VISUAL.TDG_ORDERS_SET_QUERY(RDATA_GRID => RDG,
+ RORDERS => RO,
+ SPATTERN => '%ORDER_BY%',
+ CSQL => CSQL);
+ else
+ /* Устанавливаем стандартную сортировку */
+ CSQL := replace(CSQL, '%ORDER_BY%', 'order by T.PRIOR_PARTY asc, T.BEG_PLAN asc');
+ end if;
+ /* Разбираем его */
+ 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 => 'NFCJOBS', NVALUE => NFCJOBS);
+ PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NCOMPANY', NVALUE => NCOMPANY);
+ PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NROW_FROM', NVALUE => NROW_FROM);
+ PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NROW_TO', NVALUE => NROW_TO);
+ /* Описываем структуру записи курсора */
+ PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 1);
+ PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 2);
+ PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 3);
+ PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 4);
+ PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 5);
+ PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 6);
+ PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 7);
+ PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 8);
+ PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 9);
+ PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 10);
+ PKG_SQL_DML.DEFINE_COLUMN_DATE(ICURSOR => ICURSOR, IPOSITION => 11);
+ PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 12);
+ /* Делаем выборку */
+ if (PKG_SQL_DML.EXECUTE(ICURSOR => ICURSOR) = 0) then
+ null;
+ end if;
+ /* Обходим выбранные записи */
+ while (PKG_SQL_DML.FETCH_ROWS(ICURSOR => ICURSOR) > 0)
+ loop
+ /* Читаем данные из курсора рег. номер исполнения */
+ PKG_SQL_DML.COLUMN_VALUE_NUM(ICURSOR => ICURSOR, IPOSITION => 1, NVALUE => NFCJOBSSP);
+ /* Считываем список исполнителей строки сменного задания */
+ SWORKERS_LIST := FCJOBSSP_WORKERS_LIST_GET(NFCJOBSSP => NFCJOBSSP);
+ /* Добавляем колонки с данными */
+ PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NRN', NVALUE => NFCJOBSSP, BCLEAR => true);
+ PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NSELECT', NVALUE => 0);
+ PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
+ SNAME => 'SFCROUTLST',
+ ICURSOR => ICURSOR,
+ NPOSITION => 2);
+ PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
+ SNAME => 'SMATRES',
+ ICURSOR => ICURSOR,
+ NPOSITION => 3);
+ PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SOPER', ICURSOR => ICURSOR, NPOSITION => 4);
+ PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
+ SNAME => 'SMANPOWER',
+ ICURSOR => ICURSOR,
+ NPOSITION => 5);
+ PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
+ SNAME => 'NQUANT_PLAN',
+ ICURSOR => ICURSOR,
+ NPOSITION => 6);
+ PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
+ SNAME => 'NRESOURCE_NUMB',
+ ICURSOR => ICURSOR,
+ NPOSITION => 7);
+ PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
+ SNAME => 'NLABOUR_PLAN',
+ ICURSOR => ICURSOR,
+ NPOSITION => 8);
+ PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW, SNAME => 'SFIO', ICURSOR => ICURSOR, NPOSITION => 9);
+ PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLN(RROW => RDG_ROW,
+ SNAME => 'NPERFORM_FACT',
+ ICURSOR => ICURSOR,
+ NPOSITION => 10);
+ PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLD(RROW => RDG_ROW,
+ SNAME => 'DBEG_FACT',
+ ICURSOR => ICURSOR,
+ NPOSITION => 11);
+ PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SWORKERS_LIST', SVALUE => SWORKERS_LIST);
+ /* Добавляем строку в таблицу */
+ PKG_P8PANELS_VISUAL.TDG_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
+ end loop;
+ exception
+ when others then
+ PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR);
+ raise;
+ end;
+ /* Сериализуем описание */
+ COUT := PKG_P8PANELS_VISUAL.TDG_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => NINCLUDE_DEF);
+ end FCJOBSSP_MP_DG_GET;
+
+ /* Получение рабочих подразделения */
+ procedure WORKERS_MP_DG_GET
+ (
+ NFCJOBS in number, -- Рег. номер сменного задания
+ NPAGE_NUMBER in number, -- Номер страницы (игнорируется при NPAGE_SIZE=0)
+ NPAGE_SIZE in number, -- Количество записей на странице (0 - все)
+ CORDERS in clob, -- Сортировки
+ NINCLUDE_DEF in number, -- Признак включения описания колонок таблицы в ответ
+ COUT out clob -- Сериализованная таблица данных
+ )
+ is
+ NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса
+ RO PKG_P8PANELS_VISUAL.TDG_ORDERS; -- Сортировки
+ RDG PKG_P8PANELS_VISUAL.TDG; -- Описание таблицы
+ RDG_ROW PKG_P8PANELS_VISUAL.TDG_ROW; -- Строка таблицы
+ NROW_FROM PKG_STD.TREF; -- Номер строки с
+ NROW_TO PKG_STD.TREF; -- Номер строки по
+ CSQL clob; -- Буфер для запроса
+ ICURSOR integer; -- Курсор для исполнения запроса
+ NSUBDIV PKG_STD.TNUMBER; -- Рег. номер подразделения пользователя
+ DDOC_DATE PKG_STD.TLDATE; -- Дата сменного задания
+ NSUM_LABOUR PKG_STD.TLNUMBER; -- Сумма трудоемкости
+ NSUM_WORK_TIME PKG_STD.TLNUMBER; -- Сумма рабочего времени
+ NLOADING PKG_STD.TLNUMBER; -- Загрузка оборудования
+ NDICMUNTS_MIN PKG_STD.TREF; -- Рег. номер ед. изм. минут
+ NDICMUNTS_WD PKG_STD.TREF; -- Рег. номер ед. изм. нормочасов
+ NCLNPSPFM PKG_STD.TREF; -- Рег. номер исполнения должности
+
+ /* Считывание параметров сменного задания */
+ procedure FCJOBS_PARAMS_GET
+ (
+ NFCJOBS in number, -- Рег. номер сменного задания
+ NSUBDIV out number, -- Рег. номер подразделения
+ DDOC_DATE out date -- Дата сменного задания
+ )
+ is
+ begin
+ /* Считываем параметры сменного задания */
+ begin
+ select T.SUBDIV,
+ T.DOCDATE
+ into NSUBDIV,
+ DDOC_DATE
+ from FCJOBS T
+ where T.RN = NFCJOBS;
+ exception
+ when others then
+ P_EXCEPTION(0, 'Ошибка считывания сменного задания.');
+ end;
+ end FCJOBS_PARAMS_GET;
+ begin
+ /* Читем сортировки */
+ RO := PKG_P8PANELS_VISUAL.TDG_ORDERS_FROM_XML(CORDERS => CORDERS);
+ /* Преобразуем номер и размер страницы в номер строк с и по */
+ PKG_P8PANELS_VISUAL.UTL_ROWS_LIMITS_CALC(NPAGE_NUMBER => NPAGE_NUMBER,
+ NPAGE_SIZE => NPAGE_SIZE,
+ NROW_FROM => NROW_FROM,
+ NROW_TO => NROW_TO);
+ /* Инициализируем таблицу данных */
+ RDG := PKG_P8PANELS_VISUAL.TDG_MAKE(BFIXED_HEADER => true, NFIXED_COLUMNS => 4);
+ /* Описываем колонки таблицы данных */
+ PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
+ SNAME => 'NRN',
+ SCAPTION => 'Рег. номер',
+ SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
+ BVISIBLE => false);
+ PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
+ SNAME => 'NSELECT',
+ SCAPTION => 'Выбран',
+ SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB);
+ PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
+ SNAME => 'SFIO',
+ SCAPTION => 'ФИО',
+ SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
+ BORDER => true);
+ PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
+ SNAME => 'SPROFESSION',
+ SCAPTION => 'Профессия',
+ SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
+ BORDER => true);
+ PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
+ SNAME => 'NSUM_LABOUR',
+ SCAPTION => 'Загрузка в н/ч',
+ SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
+ BORDER => true);
+ PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
+ SNAME => 'NLOADING',
+ SCAPTION => 'Загрузка в %',
+ SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
+ BORDER => true);
+ PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
+ SNAME => 'NEQUIPMENT',
+ SCAPTION => 'Рег. номер оборудования',
+ SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
+ BVISIBLE => false);
+ /* Считываем единицу измерения минут */
+ FIND_DICMUNTS_CODE(NFLAG_SMART => 0,
+ NFLAG_OPTION => 0,
+ NCOMPANY => NCOMPANY,
+ SMEAS_MNEMO => SDICMUNTS_MIN,
+ NRN => NDICMUNTS_MIN);
+ /* Считываем единицу измерения минут */
+ FIND_DICMUNTS_CODE(NFLAG_SMART => 0,
+ NFLAG_OPTION => 0,
+ NCOMPANY => NCOMPANY,
+ SMEAS_MNEMO => SDICMUNTS_WD,
+ NRN => NDICMUNTS_WD);
+ /* Считываем параметры сменного задания */
+ FCJOBS_PARAMS_GET(NFCJOBS => NFCJOBS, NSUBDIV => NSUBDIV, DDOC_DATE => DDOC_DATE);
+ /* Если подразделение считано */
+ if (NSUBDIV is not null) then
+ /* Обходим данные */
+ begin
+ /* Добавляем подсказку совместимости */
+ CSQL := PKG_SQL_BUILD.COMPATIBLE(SSQL => CSQL);
+ /* Формируем запрос */
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => 'select *');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from (select D.*,');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => PKG_SQL_BUILD.SQLROWNUM() || ' NROW');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from (select C.RN NRN,');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' (select AG.AGNFAMILYNAME||'' ''||AG.AGNFIRSTNAME||'' ''||AG.AGNLASTNAME from AGNLIST AG where AG.RN = PR.PERS_AGENT) SFIO,');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' D.PSDEP_CODE SPROFESSION');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from SUBDIVSMP T,');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' CLNPSDEP D,');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' CLNPSPFM C,');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' CLNPSPFMTYPES CT,');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' CLNPERSONS PR');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' where T.PRN = :NSUBDIV');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and T.CLNPSDEP is not null');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and exists (select null');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from SUBDIVSMPFC F,');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' ENPERIOD E');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' where F.PRN = T.RN');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and E.RN = F.PERIOD');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and E.STARTDATE <= :DDOC_DATE');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and E.ENDDATE >= :DDOC_DATE');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' ' || PKG_SQL_BUILD.ROWLIMIT(NLIMIT => 1, BAND => true) || ')');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and D.RN = T.CLNPSDEP');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and C.PSDEPRN = D.RN');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and C.BEGENG <= :DDOC_DATE');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and (C.ENDENG >= :DDOC_DATE or C.ENDENG is null)');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and C.CLNPSPFMTYPES = CT.RN');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and CT.IS_PRIMARY = ' || PKG_SQL_BUILD.WRAP_NUM(NVALUE => 1));
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and C.PERSRN = PR.RN');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' %ORDER_BY%) D) F');
+ PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' where F.NROW between :NROW_FROM and :NROW_TO');
+ /* Учтём сортировки */
+ PKG_P8PANELS_VISUAL.TDG_ORDERS_SET_QUERY(RDATA_GRID => RDG,
+ RORDERS => RO,
+ SPATTERN => '%ORDER_BY%',
+ CSQL => CSQL);
+ /* Разбираем его */
+ 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 => 'NSUBDIV', NVALUE => NSUBDIV);
+ PKG_SQL_DML.BIND_VARIABLE_DATE(ICURSOR => ICURSOR, SNAME => 'DDOC_DATE', DVALUE => DDOC_DATE);
+ PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NROW_FROM', NVALUE => NROW_FROM);
+ PKG_SQL_DML.BIND_VARIABLE_NUM(ICURSOR => ICURSOR, SNAME => 'NROW_TO', NVALUE => NROW_TO);
+ /* Описываем структуру записи курсора */
+ PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 1);
+ PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 2);
+ PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 3);
+ PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 4);
+ /* Делаем выборку */
+ if (PKG_SQL_DML.EXECUTE(ICURSOR => ICURSOR) = 0) then
+ null;
+ end if;
+ /* Обходим выбранные записи */
+ while (PKG_SQL_DML.FETCH_ROWS(ICURSOR => ICURSOR) > 0)
+ loop
+ /* Читаем данные из курсора рег. номер исполнения */
+ PKG_SQL_DML.COLUMN_VALUE_NUM(ICURSOR => ICURSOR, IPOSITION => 1, NVALUE => NCLNPSPFM);
+ /* Обнуляем сумму рабочего времени и трудоемкости */
+ NSUM_LABOUR := 0;
+ NSUM_WORK_TIME := 0;
+ /* Цикл по различным сменам данного оборудования */
+ for REC in (select TMP.TBOPERMODESP,
+ sum(TMP.NLABOUR) NLABOUR
+ from (select COALESCE(T.TBOPERMODESP, J.TBOPERMODESP) TBOPERMODESP,
+ F_DICMUNTS_BASE_RECALC_QUANT(0, T.COMPANY, T.MUNIT, T.LABOUR_PLAN, NDICMUNTS_MIN) NLABOUR
+ from FCJOBS J,
+ FCJOBSSP T
+ where J.RN = NFCJOBS
+ and T.PRN = J.RN
+ and T.PERFORM_FACT = NCLNPSPFM
+ union all
+ select COALESCE(TS.TBOPERMODESP, JS.TBOPERMODESP),
+ F_DICMUNTS_BASE_RECALC_QUANT(0, RS.COMPANY, RS.MUNIT, RS.LABOUR_PLAN, NDICMUNTS_MIN)
+ from FCJOBS JS,
+ FCJOBSSP TS,
+ FCJOBSSPAR RS
+ where JS.RN = NFCJOBS
+ and TS.PRN = JS.RN
+ and RS.PRN = TS.RN
+ and RS.PERFORM_FACT = NCLNPSPFM) TMP
+ group by TMP.TBOPERMODESP)
+ loop
+ /* Рассчитываем суммы */
+ NSUM_LABOUR := NSUM_LABOUR + REC.NLABOUR;
+ NSUM_WORK_TIME := NSUM_WORK_TIME + UTL_WORK_TIME_GET(NTBOPERMODESP => REC.TBOPERMODESP);
+ end loop;
+ /* Если оборудование не участвует в сменном задании */
+ if (NSUM_WORK_TIME = 0) then
+ NLOADING := 0;
+ else
+ NLOADING := ROUND(NSUM_LABOUR / NSUM_WORK_TIME * 100, 0);
+ /* Если трудоемкость не равна 0 */
+ if (NSUM_LABOUR <> 0) then
+ /* Переводим суммарную трудоемкость в нормочасы */
+ NSUM_LABOUR := ROUND(F_DICMUNTS_BASE_RECALC_QUANT(0, NCOMPANY, NDICMUNTS_MIN, NSUM_LABOUR, NDICMUNTS_WD),
+ 2);
+ end if;
+ end if;
+ /* Добавляем колонки с данными */
+ PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NRN', NVALUE => NCLNPSPFM, BCLEAR => true);
+ PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NSELECT', NVALUE => 0);
+ PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NSUM_LABOUR', NVALUE => NSUM_LABOUR);
+ PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
+ SNAME => 'SFIO',
+ ICURSOR => ICURSOR,
+ NPOSITION => 2);
+ PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NLOADING', NVALUE => NLOADING);
+ PKG_P8PANELS_VISUAL.TDG_ROW_ADD_CUR_COLS(RROW => RDG_ROW,
+ SNAME => 'SPROFESSION',
+ ICURSOR => ICURSOR,
+ NPOSITION => 3);
+ /* Добавляем строку в таблицу */
+ PKG_P8PANELS_VISUAL.TDG_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
+ end loop;
+ exception
+ when others then
+ PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR);
+ raise;
+ end;
+ end if;
+ /* Сериализуем описание */
+ COUT := PKG_P8PANELS_VISUAL.TDG_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => NINCLUDE_DEF);
+ end WORKERS_MP_DG_GET;
+
+ /* Инициализация записей раздела "Планы и отчеты производства изделий" */
+ procedure FCJOBS_MP_INIT
+ (
+ NFCJOBS in number, -- Рег. номер записи сменного задания
+ COUT out clob -- Информация о записи сменного задания
+ )
+ is
+ NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса
+ NVERSION PKG_STD.TREF; -- Версия контрагентов
+ SDOC_INFO PKG_STD.TSTRING; -- Информация о документе
+
+ /* Проверка доступности действия над выбранным сменным заданием */
+ procedure ACTION_AVAILABLE
+ (
+ NFCJOBS in number -- Рег. номер записи сменного задания
+ )
+ is
+ NAVAILABLE PKG_STD.TNUMBER; -- Признак доступности действия (0 - нет, 1 - да)
+ begin
+ /* Если "Состояние" <> "Не отработано" и дата документа < текущей даты - действие недоступно */
+ begin
+ select 0
+ into NAVAILABLE
+ from FCJOBS T
+ where T.RN = NFCJOBS
+ and ((T.STATE <> 0) or (T.DOCDATE < TRUNC(sysdate)));
+ exception
+ when others then
+ /* Действие доступно */
+ NAVAILABLE := 1;
+ end;
+ /* Если действие недоступно - выводим ошибку */
+ if (NAVAILABLE = 0) then
+ P_EXCEPTION(0,
+ 'Действие "Выдача сменного задания на участок" недоступно для сменного задания с состоянием отличным от "Не отработано" или датой документа ранее текущей даты.');
+ end if;
+ end ACTION_AVAILABLE;
+ begin
+ /* Проверяем доступность действия */
+ ACTION_AVAILABLE(NFCJOBS => NFCJOBS);
+ /* Считываем версию контрагентов */
+ FIND_VERSION_BY_COMPANY(NCOMPANY => NCOMPANY, SUNITCODE => 'AGNLIST', NVERSION => NVERSION);
+ /* Начинаем формирование XML */
+ PKG_XFAST.PROLOGUE(ITYPE => PKG_XFAST.CONTENT_);
+ /* Открываем корень */
+ PKG_XFAST.DOWN_NODE(SNAME => 'XDATA');
+ /* Цикл по планам и отчетам производства изделий */
+ for REC in (select T.RN NRN,
+ trim(T.DOCNUMB) SDOC_NUMB,
+ DT.DOCCODE || ', ' || trim(T.DOCPREF) || '-' || trim(T.DOCNUMB) || ', ' ||
+ TO_CHAR(T.DOCDATE, 'dd.mm.yyyy') SDOC_INFO,
+ INS.NAME SSUBDIV,
+ case
+ when PER.RN is not null then
+ TO_CHAR(T.DOCDATE, 'dd.mm.yyyy') || ' ' || TN2S(PER.BEG_TIME) || ' - ' || TN2S(PER.END_TIME)
+ else
+ TO_CHAR(T.DOCDATE, 'dd.mm.yyyy')
+ end SPERIOD,
+ (select trim(T2.NUMB) from TBOPERMODESP T2 where T.TBOPERMODESP = T2.RN) STBOPERMODESP,
+ (select 1
+ from FCJOBSSP S
+ where S.PRN = T.RN
+ and S.NOTE is not null
+ and ROWNUM = 1) NHAVE_NOTE
+ from FCJOBS T,
+ DOCTYPES DT,
+ INS_DEPARTMENT INS,
+ TBOPERMODESP PER
+ where T.RN = NFCJOBS
+ and DT.RN = T.DOCTYPE
+ and T.SUBDIV = INS.RN(+)
+ and T.TBOPERMODESP = PER.RN(+)
+ order by SDOC_INFO)
+ loop
+ /* Если указана смена */
+ if (REC.STBOPERMODESP is not null) then
+ /* Указываем информацию документа со сменой */
+ SDOC_INFO := REC.SDOC_INFO || ', смена ' || REC.STBOPERMODESP;
+ else
+ /* Указываем информацию документа без смены */
+ SDOC_INFO := REC.SDOC_INFO;
+ end if;
+ /* Открываем план */
+ PKG_XFAST.DOWN_NODE(SNAME => 'XFCJOBS');
+ /* Описываем план */
+ PKG_XFAST.ATTR(SNAME => 'NRN', NVALUE => REC.NRN);
+ PKG_XFAST.ATTR(SNAME => 'SDOC_INFO', SVALUE => SDOC_INFO);
+ PKG_XFAST.ATTR(SNAME => 'SDOC_NUMB', SVALUE => REC.SDOC_NUMB);
+ PKG_XFAST.ATTR(SNAME => 'SSUBDIV', SVALUE => REC.SSUBDIV);
+ PKG_XFAST.ATTR(SNAME => 'SPERIOD', SVALUE => REC.SPERIOD);
+ PKG_XFAST.ATTR(SNAME => 'NHAVE_NOTE', NVALUE => COALESCE(REC.NHAVE_NOTE, 0));
+ /* Закрываем план */
+ PKG_XFAST.UP();
+ end loop;
+ /* Закрываем корень */
+ PKG_XFAST.UP();
+ /* Сериализуем */
+ COUT := PKG_XFAST.SERIALIZE_TO_CLOB();
+ /* Завершаем формирование XML */
+ PKG_XFAST.EPILOGUE();
+ exception
+ when others then
+ /* Завершаем формирование XML */
+ PKG_XFAST.EPILOGUE();
+ /* Вернем ошибку */
+ PKG_STATE.DIAGNOSTICS_STACKED();
+ P_EXCEPTION(0, PKG_STATE.SQL_ERRM());
+ end FCJOBS_MP_INIT;
end PKG_P8PANELS_MECHREC;
/
diff --git a/p8panels.config b/p8panels.config
index 0fb505c..98fda93 100644
--- a/p8panels.config
+++ b/p8panels.config
@@ -120,6 +120,16 @@
icon="psychology"
showInPanelsList="true"
preview="./img/mech_rec_cost_jobs_manage.jpg"/>
+