diff --git a/app/panels/rrp_conf_editor/IUD/iud_form_dialog.js b/app/panels/rrp_conf_editor/IUD/iud_form_dialog.js deleted file mode 100644 index 61b41c7..0000000 --- a/app/panels/rrp_conf_editor/IUD/iud_form_dialog.js +++ /dev/null @@ -1,358 +0,0 @@ -/* - Парус 8 - Панели мониторинга - РО - Редактор настройки регламентированного отчёта - Панель мониторинга: Диалог добавления/исправления/удаления компонентов настройки регламентированного отчёта -*/ - -//--------------------- -//Подключение библиотек -//--------------------- - -import React, { useState, useContext, useCallback, useEffect } from "react"; //Классы React -import PropTypes from "prop-types"; //Контроль свойств компонента -import { Dialog, DialogTitle, IconButton, Icon, DialogContent, Typography, DialogActions, Button } from "@mui/material"; //Интерфейсные компоненты -import { ApplicationСtx } from "../../../context/application"; //Контекст приложения -import { BackEndСtx } from "../../../context/backend"; //Контекст взаимодействия с сервером -import { IUDFormTextField } from "./iud_form_text_field"; //Компонент поля ввода - -//--------- -//Константы -//--------- - -//Стили -const STYLES = { - CLOSE_BUTTON: { - position: "absolute", - right: 8, - top: 8, - color: theme => theme.palette.grey[500] - }, - PADDING_DIALOG_BUTTONS_RIGHT: { paddingRight: "32px" } -}; - -//Статусы диалогового окна -export const STATUSES = { CREATE: 0, EDIT: 1, DELETE: 2, RRPCONFSCTNMRK_CREATE: 3, RRPCONFSCTNMRK_EDIT: 4, RRPCONFSCTNMRK_DELETE: 5 }; - -//--------------- -//Тело компонента -//--------------- - -const IUDFormDialog = ({ initial, onClose, onReload }) => { - //Собственное состояние - const [formData, setFormData] = useState({ ...initial }); - - //Подключение к контексту приложения - const { pOnlineShowDictionary } = useContext(ApplicationСtx); - - //Подключение к контексту взаимодействия с сервером - const { executeStored } = useContext(BackEndСtx); - - //При закрытии диалога без изменений - const handleCancel = () => (onClose ? onClose() : null); - - //При закрытии диалога с изменениями - const handleOK = () => { - if (onClose) { - changeSections(); - onClose(); - } else null; - }; - - //Отработка добавления/изсправления/удаления элемента - const handleReload = () => { - if (onReload) { - onReload(); - } else null; - }; - - //При изменении значения элемента - const handleDialogItemChange = (item, value) => { - setFormData(pv => ({ ...pv, [item]: value })); - }; - - //Отработка изменений в разделе или показателе раздела - const changeSections = useCallback(async () => { - switch (formData.status) { - case STATUSES.CREATE: - await insertSections(); - break; - case STATUSES.EDIT: - await updateSections(); - break; - case STATUSES.DELETE: - await deleteSections(); - break; - case STATUSES.RRPCONFSCTNMRK_CREATE: - await addRRPCONFSCTNMRK(); - break; - case STATUSES.RRPCONFSCTNMRK_EDIT: - await editRRPCONFSCTNMRK(); - break; - case STATUSES.RRPCONFSCTNMRK_DELETE: - await deleteRRPCONFSCTNMRK(); - break; - } - handleReload(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [formData]); - - //Добавление раздела - const insertSections = useCallback(async () => { - const data = await executeStored({ - stored: "PKG_P8PANELS_RRPCONFED.RRPCONFSCTN_INSERT", - args: { - NPRN: formData.prn, - SCODE: formData.code, - SNAME: formData.name - } - }); - setFormData(pv => ({ - ...pv, - rn: Number(data.NRN) - })); - }, [formData.prn, formData.code, formData.name, executeStored]); - - //Исправление раздела - const updateSections = useCallback(async () => { - await executeStored({ - stored: "PKG_P8PANELS_RRPCONFED.RRPCONFSCTN_UPDATE", - args: { - NRN: formData.rn, - SCODE: formData.code, - SNAME: formData.name - } - }); - }, [formData.name, formData.code, formData.rn, executeStored]); - - //Удаление раздела - const deleteSections = useCallback(async () => { - await executeStored({ - stored: "PKG_P8PANELS_RRPCONFED.RRPCONFSCTN_DELETE", - args: { - NRN: formData.rn - } - }); - }, [formData.rn, executeStored]); - - //Добавление показателя раздела - const addRRPCONFSCTNMRK = useCallback(async () => { - await executeStored({ - stored: "PKG_P8PANELS_RRPCONFED.RRPCONFSCTNMRK_INSERT", - args: { - NPRN: formData.prn, - SCODE: formData.code, - SNAME: formData.name, - NRRPROW: formData.rowRn, - NRRPCOLUMN: formData.colRn - } - }); - }, [executeStored, formData.code, formData.colRn, formData.name, formData.prn, formData.rowRn]); - - //Исправление показателя раздела - const editRRPCONFSCTNMRK = useCallback(async () => { - await executeStored({ - stored: "PKG_P8PANELS_RRPCONFED.RRPCONFSCTNMRK_UPDATE", - args: { NRN: formData.rn, SNAME: formData.name } - }); - }, [executeStored, formData.name, formData.rn]); - - //Удаление показателя раздела - const deleteRRPCONFSCTNMRK = useCallback(async () => { - await executeStored({ stored: "PKG_P8PANELS_RRPCONFED.RRPCONFSCTNMRK_DELETE", args: { NRN: formData.rn } }); - }, [executeStored, formData.rn]); - - //Формирование заголовка диалогового окна - const formTitle = () => { - switch (formData.status) { - case STATUSES.CREATE: - return "Добавление раздела"; - case STATUSES.EDIT: - return "Исправление раздела"; - case STATUSES.DELETE: - return "Удаление раздела"; - case STATUSES.RRPCONFSCTNMRK_CREATE: - return "Добавление показателя раздела"; - case STATUSES.RRPCONFSCTNMRK_EDIT: - return "Исправление показателя раздела"; - case STATUSES.RRPCONFSCTNMRK_DELETE: - return "Удаление показателя раздела"; - } - }; - - //Отрисовка диалогового окна - const renderSwitch = () => { - let btnText = ""; - switch (formData.status) { - case STATUSES.CREATE: - case STATUSES.RRPCONFSCTNMRK_CREATE: - btnText = "Добавить"; - break; - case STATUSES.EDIT: - case STATUSES.RRPCONFSCTNMRK_EDIT: - btnText = "Исправить"; - break; - case STATUSES.DELETE: - case STATUSES.RRPCONFSCTNMRK_DELETE: - btnText = "Удалить"; - break; - } - return ( - - ); - }; - - //Выбор строки - const selectRow = (showDictionary, callBack) => { - showDictionary({ - unitCode: "RRPRow", - inputParameters: [{ name: "in_RN", value: formData.rowRn }], - callBack: res => { - if (res.success === true) { - callBack(res.outParameters.out_CODE, res.outParameters.out_RN); - setFormData(pv => ({ - ...pv, - reload: true, - rowCode: res.outParameters.out_CODE, - rowRn: res.outParameters.out_RN - })); - } else callBack(null); - } - }); - }; - - //Выбор графы - const selectColumn = (showDictionary, callBack) => { - showDictionary({ - unitCode: "RRPColumn", - inputParameters: [{ name: "in_RN", value: formData.colRn }], - callBack: res => { - if (res.success === true) { - callBack(res.outParameters.out_CODE, res.outParameters.out_RN); - setFormData(pv => ({ - ...pv, - reload: true, - colCode: res.outParameters.out_CODE, - colRn: res.outParameters.out_RN - })); - } else callBack(null); - } - }); - }; - - //Получение мнемокода и наименования показателя раздела - const getSctnMrkCodeName = useCallback(async () => { - const data = await executeStored({ - stored: "PKG_P8PANELS_RRPCONFED.RRPCONFSCTNMRK_GET_CODE_NAME", - args: { - NRRPCONFSCTN: formData.prn, - NRRPROW: formData.rowRn, - NRRPCOLUMN: formData.colRn - } - }); - setFormData(pv => ({ - ...pv, - reload: false, - code: data.SCODE, - name: data.SNAME - })); - }, [executeStored, formData.colRn, formData.prn, formData.rowRn]); - - //Считывание наименования показателя - const getMarkName = useCallback(async () => { - const data = await executeStored({ - stored: "PKG_P8PANELS_RRPCONFED.RRPCONFSCTNMRK_GET_NAME", - args: { - NRRPCONFSCTNMRK: formData.rn - } - }); - setFormData(pv => ({ - ...pv, - reload: false, - name: data.SNAME - })); - }, [executeStored, formData.rn]); - - //Получение наименования и мнемокода показателя раздела при заполнении необходимых полей - useEffect(() => { - //Если это добавление показателя и требуется сформировать мнемокод и наименование - formData.status == STATUSES.RRPCONFSCTNMRK_CREATE && formData.reload && formData.rowRn && formData.colRn ? getSctnMrkCodeName() : null; - //Если это исправление и требуется инициализировать наименование показателя - formData.status == STATUSES.RRPCONFSCTNMRK_EDIT && formData.reload ? getMarkName() : null; - }, [formData.status, formData.reload, formData.rowRn, formData.colRn, getSctnMrkCodeName, getMarkName]); - - //Генерация содержимого - return ( - - {formTitle()} - - close - - - {formData.status == STATUSES.DELETE || formData.status == STATUSES.RRPCONFSCTNMRK_DELETE ? ( - formData.status == STATUSES.DELETE ? ( - Вы хотите удалить раздел {formData.name}? - ) : ( - Вы хотите удалить показатель раздела {formData.name}? - ) - ) : ( -
- {formData.status != STATUSES.RRPCONFSCTNMRK_EDIT ? ( - - ) : null} - - {formData.status == STATUSES.RRPCONFSCTNMRK_CREATE ? ( -
- selectRow(pOnlineShowDictionary, callBack)} - /> - selectColumn(pOnlineShowDictionary, callBack)} - /> -
- ) : null} -
- )} -
- - {renderSwitch()} - - -
- ); -}; - -//Контроль свойств - Диалог -IUDFormDialog.propTypes = { - initial: PropTypes.object.isRequired, - onClose: PropTypes.func, - onReload: PropTypes.func -}; - -//-------------------- -//Интерфейс компонента -//-------------------- - -export { IUDFormDialog }; diff --git a/app/panels/rrp_conf_editor/IUD/iud_form_text_field.js b/app/panels/rrp_conf_editor/IUD/iud_form_text_field.js deleted file mode 100644 index 4d16ea0..0000000 --- a/app/panels/rrp_conf_editor/IUD/iud_form_text_field.js +++ /dev/null @@ -1,87 +0,0 @@ -/* - Парус 8 - Панели мониторинга - РО - Редактор настройки регламентированного отчёта - Панель мониторинга: Компонент поля ввода -*/ - -//--------------------- -//Подключение библиотек -//--------------------- - -import React, { useState, useEffect } from "react"; //Классы React -import PropTypes from "prop-types"; //Контроль свойств компонента -import { Box, FormControl, InputLabel, Input, InputAdornment, IconButton, Icon } from "@mui/material"; //Интерфейсные компоненты - -//--------- -//Константы -//--------- - -//Стили -const STYLES = { - DIALOG_WINDOW_WIDTH: { width: 400 } -}; - -//--------------- -//Тело компонента -//--------------- - -//Поле ввода -const IUDFormTextField = ({ elementCode, elementValue, labelText, onChange, dictionary, ...other }) => { - //Значение элемента - const [value, setValue] = useState(elementValue); - - //При получении нового значения из вне - useEffect(() => { - setValue(elementValue); - }, [elementValue]); - - //Выбор значения из словаря - const handleDictionaryClick = () => - dictionary ? dictionary(res => (res ? handleChange({ target: { name: elementCode, value: res } }) : null)) : null; - - //Изменение значения элемента - const handleChange = e => { - setValue(e.target.value); - if (onChange) onChange(e.target.name, e.target.value); - }; - - //Генерация содержимого - return ( - - - {labelText} - - - list - - - ) : null - } - onChange={handleChange} - multiline - maxRows={4} - /> - - - ); -}; - -//Контроль свойств - Поле ввода -IUDFormTextField.propTypes = { - elementCode: PropTypes.string.isRequired, - elementValue: PropTypes.string, - labelText: PropTypes.string.isRequired, - onChange: PropTypes.func, - dictionary: PropTypes.func -}; - -//-------------------- -//Интерфейс компонента -//-------------------- - -export { IUDFormTextField }; diff --git a/app/panels/rrp_conf_editor/common.js b/app/panels/rrp_conf_editor/common.js new file mode 100644 index 0000000..f1888a5 --- /dev/null +++ b/app/panels/rrp_conf_editor/common.js @@ -0,0 +1,43 @@ +/* + Парус 8 - Панели мониторинга - РО - Редактор настройки регламентированного отчёта + Обще стили и константы +*/ + +//--------- +//Константы +//--------- + +//Допустимые варианты сортировки строк/граф +const COL_ROW_ORDER = [ + { name: "Номер", value: 0 }, + { name: "Код", value: 1 }, + { name: "Мнемокод", value: 2 } +]; + +//Типовые цвета +const BG_GRAY = "#e3e3e3"; +const BG_BLUE = "#1976d210"; + +//Типовые размеры шрифтов +const FONT_SIZE_LARGE = "0.85rem"; +const FONT_SIZE_SMALL = "0.75rem"; + +//Стили +const STYLES = { + TOOLBAR: { position: "absolute", right: 0, backgroundColor: BG_BLUE }, + LINK: { component: "button", cursor: "pointer", width: "-webkit-fill-available" }, + FONT_DATA_GRID: { fontSize: FONT_SIZE_SMALL }, + FONT_MARK_CARD_HEAD: { fontSize: FONT_SIZE_LARGE }, + FONT_MARK_CARD_BODY: { fontSize: FONT_SIZE_SMALL }, + BG_DATA_GRID_HEAD_CELL: { backgroundColor: BG_GRAY }, + BG_DATA_GRID_DATA_CELL: { backgroundColor: BG_GRAY }, + BG_MARK_CARD: { backgroundColor: BG_BLUE }, + BORDER_DATA_GRID_HEAD_CELL: { border: "1px solid white" }, + BORDER_DATA_GRID_DATA_CELL: { borderBottom: `1px solid ${BG_GRAY}` } +}; + +//---------------- +//Интерфейс модуля +//---------------- + +export { COL_ROW_ORDER, STYLES }; diff --git a/app/panels/rrp_conf_editor/components/action_message.js b/app/panels/rrp_conf_editor/components/action_message.js new file mode 100644 index 0000000..a355178 --- /dev/null +++ b/app/panels/rrp_conf_editor/components/action_message.js @@ -0,0 +1,59 @@ +/* + Парус 8 - Панели мониторинга - РО - Редактор настройки регламентированного отчёта + Компонент панели: Сообщение с действиями +*/ + +//--------------------- +//Подключение библиотек +//--------------------- + +import React from "react"; //Классы React +import PropTypes from "prop-types"; //Контроль свойств компонента +import { Icon, Stack, Typography } from "@mui/material"; //Интерфейсные элементы + +//--------- +//Константы +//--------- + +//Стили +const STYLES = { + CONTAINER: { height: "100%", width: "100%" } +}; + +//----------- +//Тело модуля +//----------- + +//Сообщение с действиями +const ActionMessage = ({ icon, title, desc, children }) => { + return ( + + + {icon} + + {title} + + + + {desc} + + + {children} + + + ); +}; + +//Контроль свойств - Сообщение с действиями +ActionMessage.propTypes = { + icon: PropTypes.string.isRequired, + title: PropTypes.string.isRequired, + desc: PropTypes.oneOfType([PropTypes.string, PropTypes.object]).isRequired, + children: PropTypes.oneOfType([PropTypes.node, PropTypes.arrayOf(PropTypes.node)]) +}; + +//---------------- +//Интерфейс модуля +//---------------- + +export { ActionMessage }; diff --git a/app/panels/rrp_conf_editor/components/dialog_help.js b/app/panels/rrp_conf_editor/components/dialog_help.js new file mode 100644 index 0000000..b6a8b43 --- /dev/null +++ b/app/panels/rrp_conf_editor/components/dialog_help.js @@ -0,0 +1,87 @@ +/* + Парус 8 - Панели мониторинга - РО - Редактор настройки регламентированного отчёта + Компонент панели: Диалог дополнительной информации +*/ + +//--------------------- +//Подключение библиотек +//--------------------- + +import React from "react"; //Классы React +import PropTypes from "prop-types"; //Контроль свойств компонента +import { Typography, List, ListItem } from "@mui/material"; //Интерфейсные элементы +import { Form } from "./form"; //Типовая форма + +//--------- +//Константы +//--------- + +//Стили +const STYLES = { + HELP_LIST_ITEM: { padding: "0px 0px 0px 5px", whiteSpace: "pre" }, + HELP_LIST_ITEM_NAME: { fontWeight: "bold", minWidth: "45px" } +}; + +//------------------------------------ +//Вспомогательные функции и компоненты +//------------------------------------ + +//Элемент списка расшифровки состава +const HelpListItem = ({ name, desc }) => { + return ( + + {name} + {` - ${desc}`} + + ); +}; + +//Контроль свойств - Элемент списка расшифровки состава +HelpListItem.propTypes = { + name: PropTypes.string.isRequired, + desc: PropTypes.string.isRequired +}; + +//----------- +//Тело модуля +//----------- + +//Диалог дополнительной информации +const DialogHelp = ({ onClose }) => { + //При закрытии диалога + const handleClose = () => onClose && onClose(); + + //Генерация содержимого + return ( +
+ Карточки показателей содержат сокращенную информацию о типе состава показателя. Список сокращений: + + + + + + + + + + + + + + + + +
+ ); +}; + +//Контроль свойств - Диалог дополнительной информации +DialogHelp.propTypes = { + onClose: PropTypes.func +}; + +//---------------- +//Интерфейс модуля +//---------------- + +export { DialogHelp }; diff --git a/app/panels/rrp_conf_editor/components/dialog_mark_iu.js b/app/panels/rrp_conf_editor/components/dialog_mark_iu.js new file mode 100644 index 0000000..5c726f1 --- /dev/null +++ b/app/panels/rrp_conf_editor/components/dialog_mark_iu.js @@ -0,0 +1,103 @@ +/* + Парус 8 - Панели мониторинга - РО - Редактор настройки регламентированного отчёта + Компонент панели: Диалог добавления/исправления показателя +*/ + +//--------------------- +//Подключение библиотек +//--------------------- + +import React from "react"; //Классы React +import PropTypes from "prop-types"; //Контроль свойств компонента +import { useDictionary } from "../hooks"; //Кастомные хуки +import { Form } from "./form"; //Типовая форма + +//----------- +//Тело модуля +//----------- + +//Диалог добавления/исправления показателя +const DialogMarkIU = ({ + code = "", + name = "", + rowCode = "", + rowVersion = "", + columnCode = "", + columnVersion = "", + insert = true, + onOk, + onCancel +}) => { + //Нажатие на кнопку "Ok" + const handleOk = values => onOk && onOk({ ...values }); + + //Нажатие на кнопку "Отмена" + const handleCancel = () => onCancel && onCancel(); + + //Хуки для работы со словарями + const { selectRRPRow, selectRRPColumn } = useDictionary(); + + //Выбор строки из словаря + const selectRow = (currentFormValues, setFormValues) => { + selectRRPRow( + currentFormValues.rowCode, + currentFormValues.rowVersion, + selectResult => + selectResult && + setFormValues([ + { name: "rowCode", value: selectResult.code }, + { name: "rowVersion", value: selectResult.version } + ]) + ); + }; + + //Выбор графы из словаря + const selectColumn = (currentFormValues, setFormValues) => { + selectRRPColumn( + currentFormValues.columnCode, + currentFormValues.columnVersion, + selectResult => + selectResult && + setFormValues([ + { name: "columnCode", value: selectResult.code }, + { name: "columnVersion", value: selectResult.version } + ]) + ); + }; + + //Генерация содержимого + return ( +
+ ); +}; + +//Контроль свойств - Диалог добавления/исправления показателя +DialogMarkIU.propTypes = { + code: PropTypes.string, + name: PropTypes.string, + rowCode: PropTypes.string, + rowVersion: PropTypes.string, + columnCode: PropTypes.string, + columnVersion: PropTypes.string, + insert: PropTypes.bool, + onOk: PropTypes.func, + onCancel: PropTypes.func +}; + +//---------------- +//Интерфейс модуля +//---------------- + +export { DialogMarkIU }; diff --git a/app/panels/rrp_conf_editor/components/dialog_order.js b/app/panels/rrp_conf_editor/components/dialog_order.js new file mode 100644 index 0000000..dddf9ea --- /dev/null +++ b/app/panels/rrp_conf_editor/components/dialog_order.js @@ -0,0 +1,53 @@ +/* + Парус 8 - Панели мониторинга - РО - Редактор настройки регламентированного отчёта + Компонент панели: Диалог сортировки +*/ + +//--------------------- +//Подключение библиотек +//--------------------- + +import React from "react"; //Классы React +import PropTypes from "prop-types"; //Контроль свойств компонента +import { Form } from "./form"; //Типовая форма +import { COL_ROW_ORDER } from "../common"; //Обще стили и константы + +//----------- +//Тело модуля +//----------- + +//Диалог сортировки +const DialogOrder = ({ rowOrder = 0, columnOrder = 0, onOk, onCancel }) => { + //Нажатие на кнопку "Ok" + const handleOk = values => onOk && onOk({ ...values }); + + //Нажатие на кнопку "Отмена" + const handleCancel = () => onCancel && onCancel(); + + //Генерация содержимого + return ( + + ); +}; + +//Контроль свойств - Диалог сортировки +DialogOrder.propTypes = { + rowOrder: PropTypes.number, + columnOrder: PropTypes.number, + onOk: PropTypes.func, + onCancel: PropTypes.func +}; + +//---------------- +//Интерфейс модуля +//---------------- + +export { DialogOrder }; diff --git a/app/panels/rrp_conf_editor/components/dialog_section_iu.js b/app/panels/rrp_conf_editor/components/dialog_section_iu.js new file mode 100644 index 0000000..9694f41 --- /dev/null +++ b/app/panels/rrp_conf_editor/components/dialog_section_iu.js @@ -0,0 +1,53 @@ +/* + Парус 8 - Панели мониторинга - РО - Редактор настройки регламентированного отчёта + Компонент панели: Диалог добавления/исправления раздела +*/ + +//--------------------- +//Подключение библиотек +//--------------------- + +import React from "react"; //Классы React +import PropTypes from "prop-types"; //Контроль свойств компонента +import { Form } from "./form"; //Типовая форма + +//----------- +//Тело модуля +//----------- + +//Диалог добавления/исправления раздела +const DialogSectionIU = ({ code = "", name = "", insert = true, onOk, onCancel }) => { + //Нажатие на кнопку "Ok" + const handleOk = values => onOk && onOk({ ...values }); + + //Нажатие на кнопку "Отмена" + const handleCancel = () => onCancel && onCancel(); + + //Генерация содержимого + return ( + + ); +}; + +//Контроль свойств - Диалог добавления/исправления раздела +DialogSectionIU.propTypes = { + code: PropTypes.string, + name: PropTypes.string, + insert: PropTypes.bool, + onOk: PropTypes.func, + onCancel: PropTypes.func +}; + +//---------------- +//Интерфейс модуля +//---------------- + +export { DialogSectionIU }; diff --git a/app/panels/rrp_conf_editor/components/form.js b/app/panels/rrp_conf_editor/components/form.js new file mode 100644 index 0000000..98030ce --- /dev/null +++ b/app/panels/rrp_conf_editor/components/form.js @@ -0,0 +1,76 @@ +/* + Парус 8 - Панели мониторинга - РО - Редактор настройки регламентированного отчёта + Компонент панели: Форма +*/ + +//--------------------- +//Подключение библиотек +//--------------------- + +import React, { useEffect, useState } from "react"; //Классы React +import PropTypes from "prop-types"; //Контроль свойств компонента +import { Dialog, DialogTitle, DialogContent, DialogActions, Button } from "@mui/material"; //Интерфейсные компоненты +import { BUTTONS } from "../../../../app.text"; //Общие текстовые ресурсы +import { FORM_FILED, FormField } from "./form_field"; //Элемент формы + +//----------- +//Тело модуля +//----------- + +//Форма +const Form = ({ title, fields = [], children, onOk, onCancel, onClose }) => { + //Состояние формы + const [state, setState] = useState({}); + + //При изменении элемента формы + const handleFieldChange = (name, value) => setState(pv => ({ ...pv, [name]: value })); + + //При нажатии на "ОК" формы + const handleOk = () => onOk && onOk(state); + + //При нажатии на "Отмена" формы + const handleCancel = () => onCancel && onCancel(); + + //При нажатии на "Закрыть" формы + const handleClose = () => (onClose ? onClose() : onCancel ? onCancel() : null); + + //При подключении к старнице + useEffect(() => { + setState(fields.reduce((res, f) => ({ ...res, [f.elementCode]: f.elementValue == undefined ? null : f.elementValue }), {})); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + //Формирование представления + return ( + + {title} + + {fields.map((f, i) => ( + + ))} + {children} + + + {onOk && } + {onCancel && } + {onClose && } + + + ); +}; + +//Контроль свойств - Форма +Form.propTypes = { + title: PropTypes.string.isRequired, + fields: PropTypes.arrayOf(PropTypes.shape(FORM_FILED)), + children: PropTypes.oneOfType([PropTypes.node, PropTypes.arrayOf(PropTypes.node)]), + onOk: PropTypes.func, + onCancel: PropTypes.func, + onClose: PropTypes.func +}; + +//---------------- +//Интерфейс модуля +//---------------- + +export { Form }; diff --git a/app/panels/rrp_conf_editor/components/form_field.js b/app/panels/rrp_conf_editor/components/form_field.js new file mode 100644 index 0000000..587a1ad --- /dev/null +++ b/app/panels/rrp_conf_editor/components/form_field.js @@ -0,0 +1,149 @@ +/* + Парус 8 - Панели мониторинга - РО - Редактор настройки регламентированного отчёта + Компонент панели: Поле ввода формы +*/ + +//--------------------- +//Подключение библиотек +//--------------------- + +import React, { useState, useEffect } from "react"; //Классы React +import PropTypes from "prop-types"; //Контроль свойств компонента +import { Box, Icon, Input, InputAdornment, FormControl, Select, InputLabel, MenuItem, IconButton, Autocomplete, TextField } from "@mui/material"; //Интерфейсные компоненты + +//--------- +//Константы +//--------- + +//Формат свойств поля формы +const FORM_FILED = { + elementCode: PropTypes.string.isRequired, + elementValue: PropTypes.oneOfType([PropTypes.number, PropTypes.string, PropTypes.instanceOf(Date)]), + labelText: PropTypes.string.isRequired, + onChange: PropTypes.func, + dictionary: PropTypes.func, + list: PropTypes.array, + type: PropTypes.string, + freeSolo: PropTypes.bool, + disabled: PropTypes.bool, + formValues: PropTypes.object +}; + +//----------- +//Тело модуля +//----------- + +//Поле ввода формы +const FormField = ({ + elementCode, + elementValue, + labelText, + onChange, + dictionary, + list, + type, + freeSolo = false, + disabled = false, + formValues, + ...other +}) => { + //Значение элемента + const [value, setValue] = useState(elementValue); + + //При получении нового значения из вне + useEffect(() => { + setValue(elementValue); + }, [elementValue]); + + //Выбор значения из словаря + const handleDictionaryClick = () => dictionary && dictionary(formValues, res => (res ? res.map(i => handleChangeByName(i.name, i.value)) : null)); + + //Изменение значения элемента (по событию) + const handleChange = e => { + setValue(e.target.value); + if (onChange) onChange(e.target.name, e.target.value); + }; + + //Изменение значения элемента (по имени и значению) + const handleChangeByName = (name, value) => { + if (name === elementCode) setValue(value); + if (onChange) onChange(name, value); + }; + + //Генерация содержимого + return ( + + + {list ? ( + freeSolo ? ( + handleChangeByName(elementCode, newValue)} + onInputChange={(event, newInputValue) => handleChangeByName(elementCode, newInputValue)} + options={list} + renderInput={params => } + /> + ) : ( + <> + + {labelText} + + + + ) + ) : ( + <> + + {labelText} + + + + list + + + ) : null + } + {...(type ? { type } : {})} + onChange={handleChange} + disabled={disabled} + /> + + )} + + + ); +}; + +//Контроль свойств - Поле ввода формы +FormField.propTypes = FORM_FILED; + +//---------------- +//Интерфейс модуля +//---------------- + +export { FORM_FILED, FormField }; diff --git a/app/panels/rrp_conf_editor/components/layouts.js b/app/panels/rrp_conf_editor/components/layouts.js deleted file mode 100644 index 8d27591..0000000 --- a/app/panels/rrp_conf_editor/components/layouts.js +++ /dev/null @@ -1,343 +0,0 @@ -/* - Парус 8 - Панели мониторинга - РО - Редактор настройки регламентированного отчёта - Дополнительная разметка и вёрстка клиентских элементов -*/ - -//--------------------- -//Подключение библиотек -//--------------------- - -import React, { useState } from "react"; //Классы React -import PropTypes from "prop-types"; //Контроль свойств компонента -import { - IconButton, - Icon, - Link, - Card, - CardContent, - CardHeader, - Menu, - MenuItem, - Table, - TableRow, - TableCell, - TableBody, - Box, - Typography -} from "@mui/material"; //Интерфейсные компоненты - -//--------- -//Константы -//--------- - -//Стили -export const STYLES = { - BOX_ROW: { display: "flex", justifyContent: "center", alignItems: "center" }, - LINK_STYLE: { component: "button", cursor: "pointer", width: "-webkit-fill-available" }, - DATA_CELL: columnDef => ({ - padding: "5px 5px", - fontSize: "0.775rem", - letterSpacing: "0.005em", - textAlign: "center", - wordBreak: "break-all", - backgroundColor: columnDef.name === "SROW_NAME" ? "#b4b4b4" : "trasparent" - }), - DATA_CELL_CARD: { - padding: "0px 3px 3px 0px", - border: "1px solid lightgrey" - }, - DATA_CELL_CARD_HEADER: { - padding: "0px" - }, - DATA_CELL_CARD_SUBHEADER: { - textAlign: "left", - paddingLeft: "10px", - fontSize: "1rem", - fontWeight: "450" - }, - DATA_CELL_CARD_CONTENT: listLength => { - return { - fontSize: "0.75rem", - padding: "5px 0px", - minHeight: "105px", - maxHeight: "105px", - overflowY: "auto", - "&::-webkit-scrollbar": { - width: "8px" - }, - "&::-webkit-scrollbar-track": { - borderRadius: "8px", - backgroundColor: "#EBEBEB" - }, - "&::-webkit-scrollbar-thumb": { - borderRadius: "8px", - backgroundColor: "#b4b4b4" - }, - "&::-webkit-scrollbar-thumb:hover": { - backgroundColor: "#808080" - }, - "&:last-child": { - paddingBottom: "0px" - }, - ...(listLength === 0 ? { display: "flex", justifyContent: "center", alignItems: "center" } : null) - }; - }, - DATA_CELL_CARD_CONTEXT_FONT: { - fontSize: "0.75rem" - }, - DATA_CELL_CARD_CONTEXT_MARK: { - padding: "0px 0px 0px 10px", - borderBottom: "1px solid #EBEBEB" - }, - DATA_CELL_CN: { - textOverflow: "ellipsis", - overflow: "hidden", - whiteSpace: "pre", - padding: "0px 5px", - maxWidth: "100px", - border: "none" - }, - GRID_PANEL_CARD: { maxWidth: 400, flexDirection: "column", display: "flex" }, - MARK_INFO: { - fontSize: "0.8rem", - textAlign: "left", - textOverflow: "ellipsis", - overflow: "hidden", - whiteSpace: "pre", - maxWidth: "max-content", - width: "-webkit-fill-available" - }, - BUTTON_CN_INSERT: { - padding: "0px 8px", - marginBottom: "2px", - "& .MuiIcon-root": { - fontWeight: "bold", - fontSize: "1rem" - } - }, - HEAD_CELL: { - backgroundColor: "#b4b4b4", - textAlign: "center" - }, - HEAD_CELL_STACK: { - justifyContent: "space-around" - } -}; - -//------------------------------------ -//Вспомогательные функции и компоненты -//------------------------------------ - -//Действия карты показателя -const DataCellCardActions = ({ columnDef, menuItems, cellData, markRn }) => { - //Собственное состояние - const [cardActions, setCardActions] = useState({ anchorMenuMethods: null, openMethods: false }); - - //По нажатию на открытие меню действий - const handleMethodsMenuButtonClick = event => { - setCardActions(pv => ({ ...pv, anchorMenuMethods: event.currentTarget, openMethods: true })); - }; - - //При закрытии меню - const handleMethodsMenuClose = () => { - setCardActions(pv => ({ ...pv, anchorMenuMethods: null, openMethods: false })); - }; - return ( - - - more_vert - - - {menuItems.map(el => { - return ( - { - el.func(markRn); - handleMethodsMenuClose(); - }} - > - {el.icon} - {el.name} - - ); - })} - - - ); -}; - -//Контроль свойств - Действия карты показателя -DataCellCardActions.propTypes = { - columnDef: PropTypes.object.isRequired, - menuItems: PropTypes.array, - cellData: PropTypes.any, - markRn: PropTypes.number -}; - -//Таблица составов показателя -const MarkCnList = ({ markRn, list, handleMarkCnOpen }) => { - return ( - - - {list.map((el, index) => { - return ( - - - handleMarkCnOpen(markRn, el.NRN)}> - {el.SDESC} - - - - ); - })} - -
- ); -}; - -//Контроль свойств - Таблица составов показателя -MarkCnList.propTypes = { - markRn: PropTypes.number.isRequired, - list: PropTypes.array.isRequired, - handleMarkCnOpen: PropTypes.func.isRequired -}; - -//Ячейка таблицы строки -const DataCellContent = ({ row, columnDef, menuItems, sectionRn, handleMarkAdd, handleMarkOpen, handleMarkCnOpen, handleMarkCnInsert }) => { - //Считываем информацию о показателе - let mark = { - sectionRn: sectionRn, - data: row[columnDef.name], - nRn: row["NMARK_RN_" + columnDef.name.substring(5)], - sCode: row["SMARK_CODE_" + columnDef.name.substring(5)], - sRowCode: row["SROW_CODE"], - nRowRn: row["NROW_RN"], - sColCode: columnDef.name.substring(5), - nColRn: row["NCOL_RN_" + columnDef.name.substring(5)], - rCnList: row["MARK_CNS_" + columnDef.name.substring(5)] ? [...row["MARK_CNS_" + columnDef.name.substring(5)]] : [] - }; - - return ( - <> - {mark.nRn ? ( - - - (handleMarkOpen ? handleMarkOpen(mark.nRn) : null)}> - Состав - - {mark.rCnList.length !== 0 ? ( - handleMarkCnInsert(mark.nRn)}> - add - - ) : null} - - } - subheaderTypographyProps={STYLES.DATA_CELL_CARD_SUBHEADER} - action={} - > - - - {mark.sCode} - - - - {mark.rCnList.length !== 0 ? ( - - ) : ( - - Показатель не имеет состава - (handleMarkCnInsert ? handleMarkCnInsert(mark.nRn) : null)}> - Добавить - - - )} - - - ) : ( - - Показатель отсутствует - - handleMarkOpen ? handleMarkAdd(mark.sectionRn, mark.nRowRn, mark.sRowCode, mark.nColRn, mark.sColCode) : null - } - > - Добавить - - - )} - - ); -}; - -//Контроль свойств - Ячейка таблицы строки -DataCellContent.propTypes = { - row: PropTypes.object.isRequired, - columnDef: PropTypes.object.isRequired, - menuItems: PropTypes.array, - sectionRn: PropTypes.number.isRequired, - handleMarkAdd: PropTypes.func, - handleMarkOpen: PropTypes.func, - handleMarkCnOpen: PropTypes.func, - handleMarkCnInsert: PropTypes.func -}; - -//----------- -//Тело модуля -//----------- - -//Генерация представления ячейки c данными показателя раздела регламентированного отчета -export const confSctnMrkCellRender = ({ - row, - columnDef, - sectionRn, - handleMarkAdd, - handleMarkOpen, - handleMarkCnOpen, - handleMarkCnInsert, - menuItems -}) => { - //Иницализируем стили - let cellStyle = STYLES.DATA_CELL(columnDef); - //Считываем значение - let data = row[columnDef.name]; - //Если это не наименование строки и есть значение - columnDef.name != "SROW_NAME" && data != undefined && columnDef.visible == true - ? (data = ( - - )) - : null; - return { cellStyle: { ...cellStyle }, data: data }; -}; - -//Генерация представления ячейки заголовка группы c данными показателя раздела регламентированного отчета -export const confSctnMrkHeadCellRender = ({ columnDef }) => { - return { - cellStyle: STYLES.HEAD_CELL, - stackStyle: STYLES.HEAD_CELL_STACK, - data: columnDef.caption - }; -}; diff --git a/app/panels/rrp_conf_editor/components/mark_card.js b/app/panels/rrp_conf_editor/components/mark_card.js new file mode 100644 index 0000000..0487a42 --- /dev/null +++ b/app/panels/rrp_conf_editor/components/mark_card.js @@ -0,0 +1,122 @@ +/* + Парус 8 - Панели мониторинга - РО - Редактор настройки регламентированного отчёта + Компонент панели: Карточка показателя +*/ + +//--------------------- +//Подключение библиотек +//--------------------- + +import React, { useState } from "react"; //Классы React +import PropTypes from "prop-types"; //Контроль свойств компонента +import { Box, Card, CardContent, Typography, Link, Divider } from "@mui/material"; //Интерфейсные компоненты +import { APP_STYLES } from "../../../../app.styles"; //Общие стили приложения +import { MarkCnList } from "./mark_cn_list"; //Состав показателя +import { MarkCardToolbar } from "./mark_card_toolbar"; //Панель инструментов карточки +import { STYLES as COMMON_STYLES } from "../common"; //Общие стили и константы + +//--------- +//Константы +//--------- + +//Стили +const STYLES = { + CARD: hovered => ({ + padding: "0px 0px 0px 0px", + border: "1px solid lightgrey", + position: "relative", + ...(hovered ? COMMON_STYLES.BG_MARK_CARD : null) + }), + CARD_CONTENT_MARK_TITLE: { padding: "0px 0px 0px 0px" }, + CARD_CONTENT_MARK_CONSTITUTION: constitutionExists => ({ + padding: "8px", + height: "105px", + "&:last-child": { paddingBottom: "10px" }, + ...COMMON_STYLES.FONT_MARK_CARD_BODY, + ...(!constitutionExists ? { display: "flex", justifyContent: "center", alignItems: "center" } : null) + }), + BOX_MARK_CONSTITUTION: { + height: "100%", + width: "100%", + overflowY: "auto", + ...APP_STYLES.SCROLL + } +}; + +//----------- +//Тело модуля +//----------- + +//Карточка показателя +const MarkCard = ({ mark, code, name, constitution = [], onMarkAdd, onMarkUpdate, onMarkDelete, onMarkOpen, onMarkCnOpen, onMarkCnAdd }) => { + //Флаг нахождения указателя мыши в карточке + const [hovered, setHovered] = useState(false); + + //При попадании мыши на закладку раздела + const handleCardMouseIn = () => setHovered(true); + + //При выходе мыши из закладки раздела + const handleCardMouseOut = () => setHovered(false); + + //Флаг наличия данных в составе показателя + const constitutionExists = constitution?.length > 0; + + //Формирование представления + return mark ? ( + + + + + + + {constitutionExists ? ( + + onMarkCnOpen && onMarkCnOpen(constitutionRn)} /> + + ) : ( + + Показатель не имеет состава + + Добавить + + + )} + + + ) : ( + + Показатель отсутствует + + Добавить + + + ); +}; + +//Контроль свойств - Карточка показателя +MarkCard.propTypes = { + mark: PropTypes.number, + code: PropTypes.string, + name: PropTypes.string, + constitution: PropTypes.arrayOf(PropTypes.object), + onMarkAdd: PropTypes.func.isRequired, + onMarkUpdate: PropTypes.func.isRequired, + onMarkDelete: PropTypes.func.isRequired, + onMarkOpen: PropTypes.func.isRequired, + onMarkCnOpen: PropTypes.func.isRequired, + onMarkCnAdd: PropTypes.func.isRequired +}; + +//---------------- +//Интерфейс модуля +//---------------- + +export { MarkCard }; diff --git a/app/panels/rrp_conf_editor/components/mark_card_toolbar.js b/app/panels/rrp_conf_editor/components/mark_card_toolbar.js new file mode 100644 index 0000000..3b82ff7 --- /dev/null +++ b/app/panels/rrp_conf_editor/components/mark_card_toolbar.js @@ -0,0 +1,73 @@ +/* + Парус 8 - Панели мониторинга - РО - Редактор настройки регламентированного отчёта + Компонент панели: Панель инструментов карточки показателя +*/ + +//--------------------- +//Подключение библиотек +//--------------------- + +import React from "react"; //Классы React +import PropTypes from "prop-types"; //Контроль свойств компонента +import { Stack, IconButton, Icon, Typography, Link } from "@mui/material"; //Интерфейсные компоненты +import { STYLES as COMMON_STYLES } from "../common"; //Общие стили и константы + +//--------- +//Константы +//--------- + +//Стили +const STYLES = { + CONTAINER: { ...COMMON_STYLES.TOOLBAR, width: "100%", position: "unset", right: "unset", height: "40px" } +}; + +//----------- +//Тело модуля +//----------- + +//Панель инструментов карточки показателя +const MarkCardToolbar = ({ title, desc, onOpen, onEdit, onDelete, onCnAdd, showButtons = false }) => { + return ( + + + {showButtons ? ( + + {title} + + ) : ( + title + )} + + {showButtons && ( + + + edit + + + library_add + + + delete + + + )} + + ); +}; + +//Контроль свойств - Панель инструментов карточки показателя +MarkCardToolbar.propTypes = { + title: PropTypes.string, + desc: PropTypes.string, + onOpen: PropTypes.func.isRequired, + onEdit: PropTypes.func.isRequired, + onDelete: PropTypes.func.isRequired, + onCnAdd: PropTypes.func.isRequired, + showButtons: PropTypes.bool +}; + +//---------------- +//Интерфейс модуля +//---------------- + +export { MarkCardToolbar }; diff --git a/app/panels/rrp_conf_editor/components/mark_cn_list.js b/app/panels/rrp_conf_editor/components/mark_cn_list.js new file mode 100644 index 0000000..363d610 --- /dev/null +++ b/app/panels/rrp_conf_editor/components/mark_cn_list.js @@ -0,0 +1,67 @@ +/* + Парус 8 - Панели мониторинга - РО - Редактор настройки регламентированного отчёта + Компонент панели: Состав показателя +*/ + +//--------------------- +//Подключение библиотек +//--------------------- + +import React from "react"; //Классы React +import PropTypes from "prop-types"; //Контроль свойств компонента +import { Table, TableBody, TableRow, TableCell, Link } from "@mui/material"; //Интерфейсные компоненты +import { STYLES as COMMON_STYLES } from "../common"; //Общие стили и константы + +//--------- +//Константы +//--------- + +//Стили +const STYLES = { + DATA_CELL_CN: { + textOverflow: "ellipsis", + overflow: "hidden", + whiteSpace: "pre", + padding: "0px", + maxWidth: "100px", + border: "none", + ...COMMON_STYLES.FONT_MARK_CARD_BODY + } +}; + +//----------- +//Тело модуля +//----------- + +//Состав показателя +const MarkCnList = ({ constitution, onMarkCnOpen }) => { + return ( + + + {constitution.map((el, index) => { + return ( + + + onMarkCnOpen && onMarkCnOpen(el.NRN)}> + {el.SDESC} + + + + ); + })} + +
+ ); +}; + +//Контроль свойств - Состав показателя +MarkCnList.propTypes = { + constitution: PropTypes.array.isRequired, + onMarkCnOpen: PropTypes.func +}; + +//---------------- +//Интерфейс модуля +//---------------- + +export { MarkCnList }; diff --git a/app/panels/rrp_conf_editor/components/marks.js b/app/panels/rrp_conf_editor/components/marks.js new file mode 100644 index 0000000..b62520f --- /dev/null +++ b/app/panels/rrp_conf_editor/components/marks.js @@ -0,0 +1,182 @@ +/* + Парус 8 - Панели мониторинга - РО - Редактор настройки регламентированного отчёта + Компонент панели: Показатели раздела +*/ + +//--------------------- +//Подключение библиотек +//--------------------- + +import React, { useState, useContext } from "react"; //Классы React +import PropTypes from "prop-types"; //Контроль свойств компонента +import { Icon, Button } from "@mui/material"; //Интерфейсные элементы +import { MessagingСtx } from "../../../context/messaging"; //Контекст сообщений +import { P8PDataGrid, P8P_DATA_GRID_SIZE } from "../../../components/p8p_data_grid"; //Таблица данных +import { P8P_DATA_GRID_CONFIG_PROPS } from "../../../config_wrapper"; //Подключение компонентов к настройкам приложения +import { APP_STYLES } from "../../../../app.styles"; //Типовые стили +import { confSctnMrkCellRender, confSctnMrkHeadCellRender } from "../layouts"; //Дополнительная разметка и вёрстка клиентских элементов +import { ActionMessage } from "./action_message"; //Сообщение с действиями +import { DialogMarkIU } from "./dialog_mark_iu"; //Диалог добавления/исправления показателя +import { DialogHelp } from "./dialog_help"; //Диалог помощи +import { DialogOrder } from "./dialog_order"; //Диалог сортировки +import { useDictionary } from "../hooks"; //Кастомные хуки + +//--------- +//Константы +//--------- + +//Стили +const STYLES = { + MARKS_DG_CONTAINER: { + position: "absolute", + top: 0, + bottom: 0, + width: "100%", + height: "100%", + overflow: "auto", + border: "unset", + ...APP_STYLES.SCROLL + }, + MARKS_DG_TABLE: { tableLayout: "fixed", width: "auto" } +}; + +//----------- +//Тело модуля +//----------- + +//Показатели раздела +const Marks = ({ marks, order, marksLoading, marksInit, onRefresh, onMarkInsert, onMarkUpdate, onMarkDelete, onOrderChange }) => { + //Состояние - диалог сортировки + const [dialogOrder, setDialogOrder] = useState(false); + + //Состояние - диалог помощи + const [dialogHelp, setDialogHelp] = useState(false); + + //Состояние - Редактируемый показатель + const [modMark, setModMark] = useState(null); + + //Подключение к контексту сообщений + const { showMsgWarn } = useContext(MessagingСtx); + + //Подключение к словарям + const { showMark, showMarkCn, showMarkCnAdd } = useDictionary(); + + //Изменение состояния диалога информации + const toggleHelpDialog = () => setDialogHelp(pv => !pv); + + //Изменение состояния диалога сортировки + const toggleOrderDialog = () => setDialogOrder(pv => !pv); + + //При необходимости обновления + const handleRefresh = () => onRefresh && onRefresh(); + + //При вызове сортировки + const handleOrder = () => toggleOrderDialog(); + + //При вызове помощи + const handleHelp = () => toggleHelpDialog(); + + //Изменение состояния сортировки строк и граф + const handleOrderChange = order => { + onOrderChange && onOrderChange(order); + toggleOrderDialog(); + }; + + //При добавлении показателя + const handleMarkAdd = () => setModMark(true); + + //При добавлении показателя по указанным строке/графе + const handleMarkAddByRowCol = (row, column) => onMarkInsert({ row, column }); + + //При исправлении показателя + const handleMarkUpdate = markDesc => setModMark({ ...markDesc }); + + //При удалении показателя + const handleMarkDelete = mark => showMsgWarn("Удалить показатель?", () => onMarkDelete && onMarkDelete(mark)); + + //При переходе к показателю + const handleMarkOpen = mark => showMark(mark, res => res.success && handleRefresh()); + + //При добавлении состава показателя + const handleMarkCnAdd = mark => showMarkCnAdd(mark, res => res.success && handleRefresh()); + + //При переходе к составу показателя + const handleMarkCnOpen = (mark, constitution) => showMarkCn(mark, constitution, res => res.success && handleRefresh()); + + //При закрытии формы добавления/исправления по "ОК" + const handleIUFormOk = values => { + if (modMark === true) onMarkInsert && onMarkInsert(values, res => res && setModMark(null)); + else onMarkUpdate && onMarkUpdate({ ...modMark, ...values }, res => res && setModMark(null)); + }; + + //При закрытии формы добавления/исправления по "Отмена" + const handleIUFormCancel = () => setModMark(null); + + //Формирование представления + return ( + <> + {dialogOrder && } + {dialogHelp && } + {modMark && ( + + )} + {marksInit && + (marks ? ( + + confSctnMrkCellRender({ + ...prms, + onMarkAdd: handleMarkAddByRowCol, + onMarkUpdate: handleMarkUpdate, + onMarkDelete: handleMarkDelete, + onMarkOpen: handleMarkOpen, + onMarkCnOpen: handleMarkCnOpen, + onMarkCnAdd: handleMarkCnAdd + }) + } + headCellRender={prms => + confSctnMrkHeadCellRender({ + ...prms, + onAdd: handleMarkAdd, + onRefresh: handleRefresh, + onOrder: handleOrder, + onHelp: handleHelp + }) + } + /> + ) : ( + !marksLoading && ( + + + + ) + ))} + + ); +}; + +//Контроль свойств - Показатели раздела +Marks.propTypes = { + marks: PropTypes.object, + order: PropTypes.object.isRequired, + marksLoading: PropTypes.bool.isRequired, + marksInit: PropTypes.bool.isRequired, + onRefresh: PropTypes.func, + onMarkInsert: PropTypes.func, + onMarkUpdate: PropTypes.func, + onMarkDelete: PropTypes.func, + onOrderChange: PropTypes.func +}; + +//---------------- +//Интерфейс модуля +//---------------- + +export { Marks }; diff --git a/app/panels/rrp_conf_editor/components/marks_toolbar.js b/app/panels/rrp_conf_editor/components/marks_toolbar.js new file mode 100644 index 0000000..c9b433c --- /dev/null +++ b/app/panels/rrp_conf_editor/components/marks_toolbar.js @@ -0,0 +1,60 @@ +/* + Парус 8 - Панели мониторинга - РО - Редактор настройки регламентированного отчёта + Компонент панели: Панель инструментов показателей +*/ + +//--------------------- +//Подключение библиотек +//--------------------- + +import React from "react"; //Классы React +import PropTypes from "prop-types"; //Контроль свойств компонента +import { Stack, Icon, IconButton } from "@mui/material"; //Интерфейсные компоненты + +//--------- +//Константы +//--------- + +//Стили +const STYLES = { + CONTAINER: { width: "100%" } +}; + +//----------- +//Тело модуля +//----------- + +//Панель инструментов показателей +const MarksToolbar = ({ onAdd, onRefresh, onOrder, onHelp }) => { + //Формирование представления + return ( + + + add + + + refresh + + + sort + + + help + + + ); +}; + +//Контроль свойств - Панель инструментов показателей +MarksToolbar.propTypes = { + onAdd: PropTypes.func.isRequired, + onRefresh: PropTypes.func.isRequired, + onOrder: PropTypes.func.isRequired, + onHelp: PropTypes.func.isRequired +}; + +//---------------- +//Интерфейс модуля +//---------------- + +export { MarksToolbar }; diff --git a/app/panels/rrp_conf_editor/components/rrp_section.js b/app/panels/rrp_conf_editor/components/rrp_section.js deleted file mode 100644 index b64fe9e..0000000 --- a/app/panels/rrp_conf_editor/components/rrp_section.js +++ /dev/null @@ -1,359 +0,0 @@ -/* - Парус 8 - Панели мониторинга - РО - Редактор настройки регламентированного отчёта - Компонент панели: Раздел настройки -*/ - -//--------------------- -//Подключение библиотек -//--------------------- - -import React, { useState } from "react"; //Классы React -import PropTypes from "prop-types"; //Контроль свойств компонента -import { - Box, - IconButton, - Icon, - Dialog, - DialogTitle, - DialogContent, - Button, - Typography, - List, - ListItem, - Select, - FormControl, - InputLabel, - MenuItem, - DialogActions -} from "@mui/material"; //Интерфейсные элементы -import { P8PDataGrid, P8P_DATA_GRID_SIZE } from "../../../components/p8p_data_grid"; //Таблица данных -import { P8P_DATA_GRID_CONFIG_PROPS } from "../../../config_wrapper"; //Подключение компонентов к настройкам приложения -import { SectionTabPanel } from "./section_tab_panel"; //Компонент вкладки раздела -import { confSctnMrkCellRender, confSctnMrkHeadCellRender } from "./layouts"; //Дополнительная разметка и вёрстка клиентских элементов - -//--------- -//Константы -//--------- - -//Стили -const STYLES = { - GRID_SIZES: (height, pxOuterMenuH, pxPanelHeaderH, pxTabsH) => ({ - padding: 0, - minWidth: "98vw", - minHeight: (height - pxOuterMenuH - pxPanelHeaderH - pxTabsH) * 0.93, - maxWidth: "98vw", - maxHeight: (height - pxOuterMenuH - pxPanelHeaderH - pxTabsH) * 0.93 - }), - TABLE_CONTAINER: { - display: "flex", - justifyContent: "center", - alignItems: "center", - paddingTop: 1, - paddingBottom: 1 - }, - SECTION_ACTIONS: { display: "flex", justifyContent: "space-between", padding: "0px 5px" }, - TABLE_SCROLL: { - "&::-webkit-scrollbar": { - width: "12px", - height: "12px" - }, - "&::-webkit-scrollbar-track": { - borderRadius: "88px", - backgroundColor: "#EBEBEB" - }, - "&::-webkit-scrollbar-thumb": { - borderRadius: "88px", - backgroundColor: "#b4b4b4", - backgroundClip: "padding-box", - border: "3px solid #EBEBEB" - }, - "&::-webkit-scrollbar-thumb:hover": { - backgroundColor: "#808080" - } - }, - HELP_LIST_ITEM: { - padding: "0px 0px 0px 5px", - whiteSpace: "pre", - fontSize: "0.95rem" - }, - HELP_LIST_ITEM_NAME: { - fontWeight: "bold", - fontSize: "inherit", - minWidth: "45px" - }, - HELP_LIST_ITEM_DESC: { - fontSize: "inherit" - }, - DIALOG_ACTIONS: { justifyContent: "end", paddingRight: "24px", paddingLeft: "24px" } -}; - -//------------------------------------ -//Вспомогательные функции и компоненты -//------------------------------------ - -//Элемент списка расшифровки состава -const HelpListItem = ({ name, desc }) => { - return ( - - {name} - {` - ${desc}`} - - ); -}; - -//Контроль свойств - Элемент списка расшифровки состава -HelpListItem.propTypes = { - name: PropTypes.string.isRequired, - desc: PropTypes.string.isRequired -}; - -//Диалог дополнительной информации -const HelpDialog = ({ handleOpenHelpChange }) => { - //Генерация содержимого - return ( - - - - - Информация - - - - close - - - - - - Карточки показателей содержат сокращенную информацию о типе состава показателя. - Список сокращений: - - - - - - - - - - - - - - - - - - - ); -}; - -//Контроль свойств - Диалог дополнительной информации -HelpDialog.propTypes = { - handleOpenHelpChange: PropTypes.func.isRequired -}; - -//Диалог сортировки -const SortDialog = ({ init, handleOpenSortChange, onOrderChange }) => { - //Собственное состояние сортировки - const [order, setOrder] = useState({ row: init.rowOrder ? init.rowOrder : 0, column: init.columnOrder ? init.columnOrder : 0 }); - - //Изменеие сортировки - const handleOrderChange = e => setOrder(pv => ({ ...pv, [e.target.name]: e.target.value })); - - //Нажатие на кнопку Ok - const handleOk = () => { - onOrderChange({ rowOrder: order.row, columnOrder: order.column }); - handleOpenSortChange(); - }; - - //Кнопка "Очистить", значения по умолчанию - const handleClear = () => { - setOrder({ row: 0, column: 0 }); - }; - - //Кнопка "Отмена" - const handleCancel = () => { - handleOpenSortChange(); - }; - - //Генерация содержимого - return ( - - - - - Сортировка - - - - close - - - - - - - - Строки - - - - - - Графы - - - - - - - - - - - ); -}; - -//Контроль свойств - Диалог сортировки -SortDialog.propTypes = { - init: PropTypes.object.isRequired, - handleOpenSortChange: PropTypes.func.isRequired, - onOrderChange: PropTypes.func.isRequired -}; - -//----------- -//Тело модуля -//----------- - -//Раздел настройки -const SectionTab = ({ - section, - tabValue, - index, - order, - onOrderChange, - containerProps, - handleMarkAdd, - handleReload, - handleMarkOpen, - handleMarkCnOpen, - handleMarkCnInsert, - menuItems -}) => { - //Состояние - диалог информации - const [openHelp, setOpenHelp] = useState(false); - - //Изменение состояния диалога информации - const handleOpenHelpChange = () => { - setOpenHelp(!openHelp); - }; - - //Состояние - диалог сортировки - const [openSort, setOpenSort] = useState(false); - - //Изменение состояния диалога сортировки - const handleOpenSortChange = () => { - setOpenSort(!openSort); - }; - - //Генерация содержимого - return ( - <> - - - - handleMarkAdd(section.rn)}> - add - - handleReload()}> - refresh - - - - handleOpenSortChange()}> - sort - - handleOpenHelpChange()}> - help - - - - {section.dataLoaded && section.columnsDef.length > 3 ? ( - - - confSctnMrkCellRender({ - ...prms, - sectionRn: section.rn, - handleMarkAdd: handleMarkAdd, - handleMarkOpen: handleMarkOpen, - handleMarkCnOpen: handleMarkCnOpen, - handleMarkCnInsert: handleMarkCnInsert, - menuItems: menuItems - }) - } - headCellRender={confSctnMrkHeadCellRender} - /> - - ) : null} - - {openSort ? : null} - {openHelp ? : null} - - ); -}; - -//Контроль свойств - Раздел настройки -SectionTab.propTypes = { - section: PropTypes.object.isRequired, - tabValue: PropTypes.number, - index: PropTypes.number, - order: PropTypes.object.isRequired, - onOrderChange: PropTypes.func.isRequired, - containerProps: PropTypes.object, - handleMarkAdd: PropTypes.func, - handleReload: PropTypes.func, - handleMarkOpen: PropTypes.func, - handleMarkCnOpen: PropTypes.func, - handleMarkCnInsert: PropTypes.func, - menuItems: PropTypes.array -}; - -//---------------- -//Интерфейс модуля -//---------------- - -export { SectionTab }; diff --git a/app/panels/rrp_conf_editor/components/section.js b/app/panels/rrp_conf_editor/components/section.js new file mode 100644 index 0000000..f9bd4cd --- /dev/null +++ b/app/panels/rrp_conf_editor/components/section.js @@ -0,0 +1,152 @@ +/* + Парус 8 - Панели мониторинга - РО - Редактор настройки регламентированного отчёта + Компонент панели: Раздел настройки +*/ + +//--------------------- +//Подключение библиотек +//--------------------- + +import React, { useState, useContext, useEffect } from "react"; //Классы React +import PropTypes from "prop-types"; //Контроль свойств компонента +import { Box } from "@mui/material"; //Интерфейсные элементы +import { BackEndСtx } from "../../../context/backend"; //Контекст взаимодействия с сервером +import { useConfSectionMarks } from "../hooks"; //Кастомные хуки +import { ActionMessage } from "./action_message"; //Сообщение с действиями +import { Marks } from "./marks"; //Показатели раздела + +//--------- +//Константы +//--------- + +//Стили +const STYLES = { + CONTAINER: { width: "100%", height: "100%" }, + BOX_MARKS: { position: "relative", display: "flex", height: "100%", width: "100%" } +}; + +//----------- +//Тело модуля +//----------- + +//Раздел настройки +const Section = ({ section = null }) => { + //Состояние сортировки строк и граф + const [order, setOrder] = useState({ rowOrder: 0, columnOrder: 0 }); + + //Состояние - флаг "сокрытия" (на самом деле - отмонтирования) компонента с показателями + const [hideMarksThenLoading, setHideMarksThenLoading] = useState(false); + + //Данные раздела (показатели) + const [marks, refreshMarks, marksLoading, marksInit] = useConfSectionMarks(section, order.rowOrder, order.columnOrder); + + //Подключение к контексту взаимодействия с сервером + const { executeStored } = useContext(BackEndСtx); + + //Добавление показателя + const insertMark = async ({ code, name, row, rowCode, rowVersion, column, columnCode, columnVersion }, cb) => { + try { + await executeStored({ + stored: "PKG_P8PANELS_RRPCONFED.RRPCONFSCTNMRK_INSERT", + args: { + NPRN: section, + SCODE: code, + SNAME: name, + NRRPROW: row, + SRRPROW: rowCode, + SRRPVERSION_ROW: rowVersion, + NRRPCOLUMN: column, + SRRPCOLUMN: columnCode, + SRRPVERSION_COLUMN: columnVersion + }, + loader: false + }); + cb && cb(true); + refreshMarks(); + } catch { + cb && cb(false); + } + }; + + //Исправление показателя + const updateMark = async ({ rn, code, name, rowCode, rowVersion, columnCode, columnVersion }, cb) => { + try { + await executeStored({ + stored: "PKG_P8PANELS_RRPCONFED.RRPCONFSCTNMRK_UPDATE", + args: { + NRN: rn, + SCODE: code, + SNAME: name, + SRRPROW: rowCode, + SRRPVERSION_ROW: rowVersion, + SRRPCOLUMN: columnCode, + SRRPVERSION_COLUMN: columnVersion + }, + loader: false + }); + cb && cb(true); + refreshMarks(); + } catch { + cb && cb(false); + } + }; + + //Удаление показателя + const deleteMark = async mark => { + await executeStored({ + stored: "PKG_P8PANELS_RRPCONFED.RRPCONFSCTNMRK_DELETE", + args: { NRN: mark }, + loader: false + }); + refreshMarks(); + }; + + //Изменение сортировки + const changeOrder = order => setOrder(order); + + //Сброс ранее выставленного флага "сокрытия" (отмонтирования) компонента с показателями (так он не "мигает", когда происходит не смена раздела, в работа внутри него с показателями) + useEffect(() => { + if (hideMarksThenLoading) setHideMarksThenLoading(false); + }, [hideMarksThenLoading]); + + //При смене раздела - выставим флаг "спрятать" (отмонтировать) компонент с показателями (так он корректно полностью обновляется) + useEffect(() => { + if (section) setHideMarksThenLoading(true); + }, [section]); + + //Формирование представления + return ( + + {section ? ( + + {((hideMarksThenLoading && !marksLoading) || !hideMarksThenLoading) && ( + + )} + + ) : ( + + )} + + ); +}; + +//Контроль свойств - Раздел настройки +Section.propTypes = { + section: PropTypes.number +}; + +//---------------- +//Интерфейс модуля +//---------------- + +export { Section }; diff --git a/app/panels/rrp_conf_editor/components/section_tab.js b/app/panels/rrp_conf_editor/components/section_tab.js new file mode 100644 index 0000000..6f74d95 --- /dev/null +++ b/app/panels/rrp_conf_editor/components/section_tab.js @@ -0,0 +1,89 @@ +/* + Парус 8 - Панели мониторинга - РО - Редактор настройки регламентированного отчёта + Компонент панели: Закладка раздела +*/ + +//--------------------- +//Подключение библиотек +//--------------------- + +import React, { useState } from "react"; //Классы React +import PropTypes from "prop-types"; //Контроль свойств компонента +import { Tab, IconButton, Icon, Stack } from "@mui/material"; //Интерфейсные компоненты +import { STYLES as COMMON_STYLES } from "../common"; //Общие стили и константы + +//--------- +//Константы +//--------- + +//Стили +const STYLES = { + SECTION_TAB: { minWidth: "150px" }, + SECTION_TAB_LABEL: { width: "100%", height: "100%" }, + SECTION_TAB_TOOLBAR_STACK: { ...COMMON_STYLES.TOOLBAR, height: "100%", width: "100%" } +}; + +//----------- +//Тело модуля +//----------- + +//Закладка раздела +const SectionTab = ({ value = false, section, sectionDesc, onSectionEdit, onSectionDelete, ...other }) => { + //Флаг нахождения указателя мыши в закладке + const [hoveredSection, setHoveredSection] = useState(false); + + //При попадании мыши на закладку раздела + const handleSectionTabMouseIn = () => setHoveredSection(true); + + //При выходе мыши из закладки раздела + const handleSectionTabMouseOut = () => setHoveredSection(false); + + //При редактировании раздела настройки + const handleSectionEdit = () => onSectionEdit && onSectionEdit(sectionDesc.NRN); + + //При удалении раздела настройки + const handleSectionDelete = () => onSectionDelete && onSectionDelete(sectionDesc.NRN); + + //Формирование представления + return ( + + {`${sectionDesc.SCODE} - ${sectionDesc.SNAME_SHORT}`} + {section === sectionDesc.NRN && hoveredSection && ( + + + edit + + + delete + + + )} + + } + {...other} + /> + ); +}; + +//Контроль свойств - Закладка раздела +SectionTab.propTypes = { + value: PropTypes.any, + section: PropTypes.number, + sectionDesc: PropTypes.object.isRequired, + onSectionEdit: PropTypes.func, + onSectionDelete: PropTypes.func +}; + +//---------------- +//Интерфейс модуля +//---------------- + +export { SectionTab }; diff --git a/app/panels/rrp_conf_editor/components/section_tab_panel.js b/app/panels/rrp_conf_editor/components/section_tab_panel.js deleted file mode 100644 index 9f24331..0000000 --- a/app/panels/rrp_conf_editor/components/section_tab_panel.js +++ /dev/null @@ -1,50 +0,0 @@ -/* - Парус 8 - Панели мониторинга - РО - Редактор настройки регламентированного отчёта - Панель мониторинга: Компонент вкладки раздела -*/ - -//--------------------- -//Подключение библиотек -//--------------------- - -import React from "react"; //Классы React -import PropTypes from "prop-types"; //Контроль свойств компонента -import { Box } from "@mui/material"; //Интерфейсные компоненты - -//--------- -//Константы -//--------- - -const STYLES = { - SECTION_INFO: { - padding: "24px 5px 0px 5px" - } -}; - -//--------------- -//Тело компонента -//--------------- - -const SectionTabPanel = props => { - const { children, value, index, ...other } = props; - - //Генерация содержимого - return ( - - ); -}; - -//Контроль свойств - Вкладка раздела -SectionTabPanel.propTypes = { - children: PropTypes.node, - index: PropTypes.number.isRequired, - value: PropTypes.number.isRequired -}; - -//-------------------- -//Интерфейс компонента -//-------------------- - -export { SectionTabPanel }; diff --git a/app/panels/rrp_conf_editor/components/sections.js b/app/panels/rrp_conf_editor/components/sections.js new file mode 100644 index 0000000..4c63745 --- /dev/null +++ b/app/panels/rrp_conf_editor/components/sections.js @@ -0,0 +1,207 @@ +/* + Парус 8 - Панели мониторинга - РО - Редактор настройки регламентированного отчёта + Компонент панели: Разделы настройки +*/ + +//--------------------- +//Подключение библиотек +//--------------------- + +import React, { useState, useEffect, useContext, useCallback } from "react"; //Классы React +import PropTypes from "prop-types"; //Контроль свойств компонента +import { Box, Tabs, IconButton, Icon, Stack, Button } from "@mui/material"; //Интерфейсные компоненты +import { tabsClasses } from "@mui/material/Tabs"; //Классы закладок +import { ApplicationСtx } from "../../../context/application"; //Контекст взаимодействия с приложением +import { BackEndСtx } from "../../../context/backend"; //Контекст взаимодействия с сервером +import { MessagingСtx } from "../../../context/messaging"; //Контекст сообщений +import { useConfSections } from "../hooks"; //Кастомные хуки +import { ActionMessage } from "./action_message"; //Сообщение с действиями +import { SectionTab } from "./section_tab"; //Закладка раздела +import { DialogSectionIU } from "./dialog_section_iu"; //Диалог добавления/исправления раздела + +//--------- +//Константы +//--------- + +//Стили +const STYLES = { + CONTAINER: { borderBottom: 1, borderColor: "divider", width: "100%", height: "100%" }, + TABS_SECTIONS: { width: "100%", [`& .${tabsClasses.scrollButtons}`]: { "&.Mui-disabled": { opacity: 0.3 } } } +}; + +//----------------------- +//Вспомогательные функции +//----------------------- + +//Поиск активного раздела после удаления текущего +const getNextSectionAfterDelete = (sections, deletedSection) => { + //Находим индекс удаляемого раздела + const delInd = sections.findIndex(s => s.NRN === deletedSection); + //Возвращаем рег. номер либо предыдущего раздела, либо следующего, либо ничего + return delInd === -1 ? null : sections[delInd - 1]?.NRN || sections[delInd + 1]?.NRN || null; +}; + +//----------- +//Тело модуля +//----------- + +//Разделы настройки +const Sections = ({ conf, onSectionChange, onSectionCountChange }) => { + //Текущий раздел настройки + const [section, setSection] = useState(-1); + + //Редактируемый раздел настройки + const [modSection, setModSection] = useState(null); + + //Список разделов и просто описание настройки + const [confDesc, sections, refreshSections, sectionsLoading, sectionsInit] = useConfSections(conf); + + //Подключение к контексту приложения + const { setAppBarTitle } = useContext(ApplicationСtx); + + //Подключение к контексту взаимодействия с сервером + const { executeStored } = useContext(BackEndСtx); + + //Подключение к контексту сообщений + const { showMsgWarn } = useContext(MessagingСtx); + + //Выбор раздела + const selectSection = useCallback( + section => { + if (onSectionChange) onSectionChange(section); + setSection(section); + }, + [onSectionChange] + ); + + //Добавление раздела + const insertSection = async ({ conf, code, name }) => { + const data = await executeStored({ + stored: "PKG_P8PANELS_RRPCONFED.RRPCONFSCTN_INSERT", + args: { NPRN: conf, SCODE: code, SNAME: name }, + loader: false + }); + selectSection(data.NRN); + refreshSections(); + }; + + //Исправление раздела + const updateSection = async ({ rn, code, name }) => { + await executeStored({ + stored: "PKG_P8PANELS_RRPCONFED.RRPCONFSCTN_UPDATE", + args: { NRN: rn, SCODE: code, SNAME: name }, + loader: false + }); + refreshSections(); + }; + + //Удаление раздела + const deleteSection = async section => { + await executeStored({ + stored: "PKG_P8PANELS_RRPCONFED.RRPCONFSCTN_DELETE", + args: { NRN: section }, + loader: false + }); + selectSection(getNextSectionAfterDelete(sections, section)); + refreshSections(); + }; + + //При измении закладки текущего раздела + const handleSectionTabChange = (event, section) => selectSection(section); + + //При добавлении раздела настройки + const handleSectionAdd = () => setModSection(true); + + //При редактировании раздела настройки + const handleSectionEdit = section => setModSection(sections.find(s => s.NRN === section) || null); + + //При удалении раздела настройки + const handleSectionDelete = section => showMsgWarn("Удалить раздел?", () => deleteSection(section)); + + //При закрытии формы добавления/исправления по "ОК" + const handleIUFormOk = async values => { + if (modSection === true) await insertSection({ conf, ...values }); + else await updateSection({ rn: modSection.NRN, ...values }); + setModSection(null); + }; + + //При закрытии формы добавления/исправления по "Отмена" + const handleIUFormCancel = () => setModSection(null); + + //При изменении состава разделов + useEffect(() => { + //Если ещё не инициализировали выбранный раздел и есть чем + if (section === -1 && sections.length > 0) selectSection(sections[0].NRN); + }, [section, sections, selectSection]); + + //При изменении количества разделов + useEffect(() => { + onSectionCountChange && onSectionCountChange(sections.length); + }, [sections.length, onSectionCountChange]); + + //При изменении описания раздела + useEffect(() => { + if (confDesc?.SNAME) setAppBarTitle(confDesc.SNAME); + }, [confDesc, setAppBarTitle]); + + //Вычисление подсвеченной закладки раздела + const hlSection = sections.find(s => s.NRN === section)?.NRN || false; + + //Формирование представления + return ( + + {modSection && ( + + )} + {sections.length > 0 ? ( + <> + + + add + + + + {sections.map((s, i) => ( + + ))} + + + ) : ( + sectionsInit && + !sectionsLoading && ( + + + + ) + )} + + ); +}; + +//Контроль свойств - Разделы настройки +Sections.propTypes = { + conf: PropTypes.number, + onSectionChange: PropTypes.func, + onSectionCountChange: PropTypes.func +}; + +//---------------- +//Интерфейс модуля +//---------------- + +export { Sections }; diff --git a/app/panels/rrp_conf_editor/hooks.js b/app/panels/rrp_conf_editor/hooks.js index 72aedd9..2b85548 100644 --- a/app/panels/rrp_conf_editor/hooks.js +++ b/app/panels/rrp_conf_editor/hooks.js @@ -7,403 +7,209 @@ //Подключение библиотек //--------------------- -import { useState, useContext, useEffect, useCallback, useLayoutEffect } from "react"; //Классы React +import { useState, useContext, useEffect } from "react"; //Классы React +import { xml2JSON } from "../../core/utils"; //Вспомогательные функции import { ApplicationСtx } from "../../context/application"; //Контекст приложения import { BackEndСtx } from "../../context/backend"; //Контекст взаимодействия с сервером -import { NavigationCtx } from "../../context/navigation"; //Контекст навигации -import { MessagingСtx } from "../../context/messaging"; //Контекст сообщений -import { STATUSES } from "./IUD/iud_form_dialog"; //Статусы диалогов -import { TEXTS } from "../../../app.text"; //Тексты для ошибок //----------- //Тело модуля //----------- -//Хук для отработки изменений ширины и высоты рабочей области окна -const useWindowResize = () => { - //Состояние размера рабочей области - const [size, setSize] = useState([0, 0]); +//Получение данных о разделах настройки РО +const useConfSections = conf => { + //Собственное состояние - флаг инициализированности + const [isInit, setInit] = useState(false); - //При изменении размера - useLayoutEffect(() => { - const updateSize = () => { - setSize([document.documentElement.clientWidth, document.documentElement.clientHeight]); - }; - window.addEventListener("resize", updateSize); - updateSize(); - return () => window.removeEventListener("resize", updateSize); - }, []); + //Собственное состояние - флаг загрузки + const [isLoading, setLoading] = useState(false); - //Вернём размеры - return size; -}; + //Собственное состояние - флаг необходимости обновления + const [refresh, setRefresh] = useState(true); -//Хук для настройки регламентированного отчета -const useConf = (currentTab, handleSectionChange, order) => { - //Собственное состояние - таблица данных - const dataGrid = { - rn: 0, - code: "", - name: "", - dataLoaded: false, - columnsDef: [], - groups: [], - rows: [], - fixedHeader: false, - fixedColumns: 0, - reload: false - }; + //Собственное состояние - данные настройки + const [dataConf, setDataConf] = useState(null); - //Собственное состояние - const [rrpConf, setRrpConf] = useState({ - docLoaded: false, - sections: [], - orderChanged: false, - reload: true - }); - - //Состояние массива данных разделов - const [dataGrids] = useState([]); + //Собственное состояние - данные разделов + const [dataSections, setDataSections] = useState([]); //Подключение к контексту взаимодействия с сервером const { executeStored } = useContext(BackEndСtx); - //Подключение к контексту навигации - const { getNavigationSearch } = useContext(NavigationCtx); + //Обновление данных + const doRefresh = () => setRefresh(true); - //При необходимости обновить - const handleReload = useCallback(async () => { - setRrpConf(pv => ({ ...pv, reload: true })); - }, []); - - //Загрузка данных разделов регламентированного отчёта - const loadData = useCallback( - async () => { - if (rrpConf.reload) { - //Переменная номера раздела с фокусом - let tabFocus = currentTab ? currentTab : 0; + //При необходимости получить/обновить данные + useEffect(() => { + //Загрузка данных с сервера + const loadData = async () => { + try { + setLoading(true); const data = await executeStored({ - stored: "PKG_P8PANELS_RRPCONFED.RRPCONF_GET_SECTIONS", - args: { - NRN_RRPCONF: Number(getNavigationSearch().NRN), - NROW_ORDER: Number(order.rowOrder), - NCOL_ORDER: Number(order.columnOrder) - }, + stored: "PKG_P8PANELS_RRPCONFED.RRPCONF_GET", + args: { NRRPCONF: conf }, + respArg: "COUT", + isArray: name => name === "XSECTIONS", + attributeValueProcessor: (name, val) => (name.startsWith("S") ? undefined : val), + loader: false + }); + setDataConf(data?.XCONF || null); + setDataSections(data?.XSECTIONS || []); + setInit(true); + } finally { + setRefresh(false); + setLoading(false); + } + }; + //Если надо обновить + if (refresh) + if (conf) + //Если есть для чего получать данные + loadData(); + //Нет идентификатора настройки - нет данных + else { + setDataConf(null); + setDataSections([]); + } + }, [refresh, conf, executeStored]); + + //При изменении входных свойств - поднимаем флаг обновления + useEffect(() => setRefresh(true), [conf]); + + //Возвращаем интерфейс хука + return [dataConf, dataSections, doRefresh, isLoading, isInit]; +}; + +//Получение данных о показателях раздела настройки РО +const useConfSectionMarks = (section, rowOrder = 0, columnOrder = 0) => { + //Собственное состояние - флаг инициализированности + const [isInit, setInit] = useState(false); + + //Собственное состояние - флаг загрузки + const [isLoading, setLoading] = useState(false); + + //Собственное состояние - флаг необходимости обновления + const [refresh, setRefresh] = useState(true); + + //Собственное состояние - данные + const [data, setData] = useState(null); + + //Подключение к контексту взаимодействия с сервером + const { executeStored } = useContext(BackEndСtx); + + //Обновление данных + const doRefresh = () => setRefresh(true); + + //При необходимости получить/обновить данные + useEffect(() => { + //Загрузка данных с сервера + const loadData = async () => { + try { + setLoading(true); + const data = await executeStored({ + stored: "PKG_P8PANELS_RRPCONFED.RRPCONFSCTN_GET", + args: { NRRPCONFSCTN: section, NROW_ORDER: rowOrder, NCOL_ORDER: columnOrder }, respArg: "COUT" }); - //Флаг первой загрузки данных - let firstLoad = dataGrids.length == 0 ? true : false; - //Копирование массива уже загруженных разделов - let cloneDGs = dataGrids.slice(); - //Массив из нескольких разделов и из одного - const sections = data.SECTIONS ? (data.SECTIONS.length ? data.SECTIONS : [data.SECTIONS]) : []; - //Заполнение очередного раздела по шаблону - sections - .sort((a, b) => a.SCODE - b.SCODE) - .map(s => { - let dg = {}; - Object.assign(dg, dataGrid, { - ...s.XDATA.XDATA_GRID, - rn: s.NRN, - code: s.SCODE, - name: s.SNAME, - delete_allow: s.NDELETE_ALLOW, - dataLoaded: true, - columnsDef: [...(s.XDATA.XDATA_GRID.columnsDef || [])], - groups: [...(s.XDATA.XDATA_GRID.groups || [])], - rows: [...(s.XDATA.XDATA_GRID.rows || [])], - reload: false - }); - //Если раздел имеет составы показателей - if (s.MARK_CNS.MARK_CN) { - //Обходим строки раздела - dg.rows.map(row => { - //Цикл по ключам строки - for (let key in row) { - //Если это ключ для группы составов показателей - if (key.match(/MARK_CNS_.*/)) { - //Считываем рег. номер показателя - let markRn = key.substring(9); - //Переносим из раздела - row[key] = Array.isArray(s.MARK_CNS.MARK_CN) - ? [...s.MARK_CNS.MARK_CN].filter(el => el.NPRN === row[`NMARK_RN_${markRn}`]) - : s.MARK_CNS.MARK_CN.NPRN === row[`NMARK_RN_${markRn}`] - ? [s.MARK_CNS.MARK_CN] - : null; - } - } - }); - } - //Ищем загружен ли уже раздел с таким же ид. - const dgItem = dataGrids.find(x => x.rn === dg.rn); - //Его индекс, если нет соответствия, то -1 - let index = dataGrids.indexOf(dgItem); - //Если было соответствие - if (dgItem) { - //Если в нём не найдено изменений - if (JSON.stringify(dgItem, null, 4) === JSON.stringify(dg, null, 4)) { - //То из копированного массива его удаляем - cloneDGs.splice(cloneDGs.indexOf(cloneDGs.find(x => x.rn === dgItem.rn)), 1); - } else { - //Иначе обновляем раздел в массиве - dataGrids[index] = dg; - //Удаляем из копированного массива - cloneDGs.splice(cloneDGs.indexOf(cloneDGs.find(x => x.rn === dg.rn)), 1); - //Устанавливаем фокус на обновлённый раздел, если был добавлен - tabFocus = rrpConf.orderChanged ? 0 : index; - } - } else { - //Если раздел новый, то добавляем его в массив данных - dataGrids.push(dg); - //И устанавливаем на него фокус, если флаг первой загрузки = false - tabFocus = !firstLoad ? dataGrids.length - 1 : 0; - } - }); - //Обходим разделы, что остались в копированном массиве (на удаление) - cloneDGs.map(s => { - let curIndex = dataGrids.indexOf(dataGrids.find(x => x.rn === s.rn)); - //Устаревший раздел удаляем из массива данных - dataGrids.splice(curIndex, 1); - //Фокус на предшествующий раздел - if (curIndex > 0) tabFocus = curIndex - 1; - //Иначе фокус на следующий, если был удалён первый раздел - else tabFocus = curIndex; - }); - setRrpConf(pv => ({ - ...pv, - docLoaded: true, - orderChanged: false, - reload: false, - sections: dataGrids - })); - handleSectionChange(tabFocus); + if (data) { + for (let i = 0; i < data?.XDATA_GRID?.rows?.length; i++) + for (const key of Object.keys(data.XDATA_GRID.rows[i])) + if (key.startsWith("SCOL_")) + data.XDATA_GRID.rows[i][key] = ( + await xml2JSON({ + xmlDoc: data.XDATA_GRID.rows[i][key], + isArray: name => name === "CONSTITUTION", + attributeValueProcessor: (name, val) => (name.startsWith("S") ? undefined : val) + }) + ).XMARK; + setData(data?.XDATA_GRID || null); + } else setData(null); + setInit(true); + } finally { + setRefresh(false); + setLoading(false); } - }, - // eslint-disable-next-line react-hooks/exhaustive-deps - [rrpConf.reload, rrpConf.docLoaded, dataGrid.reload, dataGrid.docLoaded, executeStored] - ); + }; + //Если надо обновить + if (refresh) + if (section) + //Если есть для чего получать данные + loadData(); + //Нет идентификатора раздела настройки - нет данных + else setData(null); + }, [refresh, section, rowOrder, columnOrder, executeStored]); - //При изменении сортировок - useEffect(() => { - setRrpConf(pv => ({ ...pv, orderChanged: true, reload: true })); - }, [order]); + //При изменении входных свойств - поднимаем флаг обновления + useEffect(() => setRefresh(true), [section, rowOrder, columnOrder]); - //При необходимости обновить данные таблицы - useEffect(() => { - loadData(); - }, [rrpConf.reload, dataGrid.reload, loadData]); + //При изменении раздела - сбрасываем флаг инициализированности (так карточки показателей грузятся красивее - таблица исчезает и появляется уже загруженная) + useEffect(() => setInit(false), [section]); - return [rrpConf, handleReload]; + //Возвращаем интерфейс хука + return [data, doRefresh, isLoading, isInit]; }; -//Хук для вкладки -const useTab = () => { - //Состояние раздела - const [tabValue, setTabValue] = useState(""); - - //Переключение раздела - const handleSectionChange = useCallback(newValue => { - setTabValue(newValue); - }, []); - - return [tabValue, handleSectionChange]; -}; - -//Хук для функций открытия записей -const useRecOpen = handleReload => { - //Подключение к контексту взаимодействия с сервером - const { executeStored } = useContext(BackEndСtx); - +//Работа со словарями +const useDictionary = () => { //Подключение к контексту приложения const { pOnlineShowDictionary } = useContext(ApplicationСtx); - //Подключение к контексту сообщений - const { showMsgErr } = useContext(MessagingСtx); - - //Отображение показателя раздела - const handleMarkOpen = useCallback( - async nRrpConfSctnMrk => { - const data = await executeStored({ - stored: "PKG_P8PANELS_RRPCONFED.RRPCONFSCTNMRK_GET_CODES", - args: { - NRN: nRrpConfSctnMrk - }, - tagValueProcessor: () => undefined - }); - if (data) { - pOnlineShowDictionary({ - unitCode: "RRPConfig", - showMethod: "main_mrk_settings", - inputParameters: [ - { name: "in_CODE", value: data.SRRPCONF }, - { name: "in_SCTN_CODE", value: data.SRRPCONFSCTN }, - { name: "in_MRK_CODE", value: data.SRRPCONFSCTNMRK } - ], - callBack: res => { - res.success ? handleReload() : null; - } - }); - } else showMsgErr(TEXTS.NO_DATA_FOUND); - }, - [executeStored, handleReload, pOnlineShowDictionary, showMsgErr] - ); - - //Отображение показателя раздела - const handleMarkCnOpen = useCallback( - async (nRrpConfSctnMrk, nRrpConfSctnMrkCn) => { - pOnlineShowDictionary({ - unitCode: "RRPConfigSectionMark", - showMethod: "link_cn", - inputParameters: [ - { name: "in_RN", value: nRrpConfSctnMrk }, - { name: "in_RRPCONFSCTNMRKCN", value: nRrpConfSctnMrkCn } - ], - callBack: res => { - res.success ? handleReload() : null; - } - }); - }, - [handleReload, pOnlineShowDictionary] - ); - - //Отображение показателя раздела - const handleMarkCnInsert = useCallback( - async nRrpConfSctnMrk => { - pOnlineShowDictionary({ - unitCode: "RRPConfigSectionMarkConstitution", - showMethod: "link_add", - inputParameters: [{ name: "in_PRN", value: nRrpConfSctnMrk }], - callBack: res => { - res.success ? handleReload() : null; - } - }); - }, - [handleReload, pOnlineShowDictionary] - ); - - return [handleMarkOpen, handleMarkCnOpen, handleMarkCnInsert]; -}; - -//Хук для форм диалогового окна -const useFormDialog = () => { - //Состояние открытия диалогового окна - const [formOpen, setForm] = useState(false); - - //Состояние диалогового окна - const [formData, setFormData] = useState({ - reload: false, - rn: "", - prn: "", - sctnName: "", - sctnCode: "", - status: "", - code: "", - name: "", - colCode: "", - colRn: null, - rowCode: "", - rowRn: null - }); - - //Подключение к контексту навигации - const { getNavigationSearch } = useContext(NavigationCtx); - - //Открытие диалогового окна - const openForm = () => { - setForm(true); - }; - - //Очистка диалогового окна - const clearFormData = () => { - setFormData({ - reload: false, - rn: "", - prn: "", - sctnName: "", - sctnCode: "", - status: "", - code: "", - name: "", - colCode: "", - colRn: null, - rowCode: "", - rowRn: null + //Выбор строки + const selectRRPRow = (code, version, callBack) => { + pOnlineShowDictionary({ + unitCode: "RRPRow", + inputParameters: [ + { name: "in_CODE", value: code }, + { name: "in_RRPVERSION_CODE", value: version } + ], + callBack: res => + callBack(res.success === true ? { code: res.outParameters.out_CODE, version: res.outParameters.out_RRPVERSION_CODE } : null) }); }; - //Отработка нажатия на кнопку добавления секции - const handleSectionAdd = () => { - setFormData({ status: STATUSES.CREATE, prn: Number(getNavigationSearch().NRN) }); - openForm(); - }; - - //Отработка нажатия на кнопку исправления секции - const handleSectionEdit = (rn, code, name) => { - setFormData({ rn: rn, code: code, name: name, status: STATUSES.EDIT }); - openForm(); - }; - - //Отработка нажатия на кнопку удаления секции - const handleSectionDelete = (rn, code, name) => { - setFormData({ rn: rn, code: code, name: name, status: STATUSES.DELETE }); - openForm(); - }; - - //Отработка нажатия на кнопку добавления показателя раздела - const handleMarkAdd = (prn, rowRn = null, rowCode = "", colRn = null, colCode = "") => { - setFormData({ - reload: rowRn && colRn ? true : false, - prn: prn, - rowRn: rowRn, - rowCode: rowCode, - colRn: colRn, - colCode: colCode, - status: STATUSES.RRPCONFSCTNMRK_CREATE + //Выбор графы + const selectRRPColumn = (code, version, callBack) => { + pOnlineShowDictionary({ + unitCode: "RRPColumn", + inputParameters: [ + { name: "in_CODE", value: code }, + { name: "in_RRPVERSION_CODE", value: version } + ], + callBack: res => + callBack(res.success === true ? { code: res.outParameters.out_CODE, version: res.outParameters.out_RRPVERSION_CODE } : null) }); - openForm(); }; - //Отработка нажатия на кнопку исправления показателя раздела - const handleMarkEdit = rn => { - setFormData({ reload: true, rn: rn, status: STATUSES.RRPCONFSCTNMRK_EDIT }); - openForm(); - }; + //Отображение показателя раздела + const showMark = (mark, callBack) => showMarkCn(mark, null, callBack); - //Отработка нажатия на кнопку удаления показателя раздела - const handleMarkDelete = rn => { - setFormData({ rn: rn, status: STATUSES.RRPCONFSCTNMRK_DELETE }); - openForm(); - }; + //Отображение состава показателя раздела + const showMarkCn = (mark, constitution, callBack) => + pOnlineShowDictionary({ + unitCode: "RRPConfigSectionMark", + showMethod: "link_cn", + inputParameters: [ + { name: "in_RN", value: mark }, + { name: "in_RRPCONFSCTNMRKCN", value: constitution } + ], + callBack + }); - //При закрытии диалога - const handleDialogClose = () => { - setForm(false); - clearFormData(); - }; + //Отображение состава показателя раздела с добавлением + const showMarkCnAdd = (mark, callBack) => + pOnlineShowDictionary({ + unitCode: "RRPConfigSectionMarkConstitution", + showMethod: "link_add", + inputParameters: [{ name: "in_PRN", value: mark }], + callBack + }); - return [ - formOpen, - formData, - handleSectionAdd, - handleSectionEdit, - handleSectionDelete, - handleMarkAdd, - handleMarkEdit, - handleMarkDelete, - handleDialogClose - ]; -}; - -//Формирование разделов -const a11yProps = index => { - return { - id: `simple-tab-${index}`, - "aria-controls": `simple-tabpanel-${index}` - }; + //Возвращаем интерфейс хука + return { selectRRPRow, selectRRPColumn, showMark, showMarkCn, showMarkCnAdd }; }; //---------------- //Интерфейс модуля //---------------- -export { useWindowResize, useConf, useTab, useRecOpen, useFormDialog, a11yProps }; +export { useConfSections, useConfSectionMarks, useDictionary }; diff --git a/app/panels/rrp_conf_editor/layouts.js b/app/panels/rrp_conf_editor/layouts.js new file mode 100644 index 0000000..4ae83b3 --- /dev/null +++ b/app/panels/rrp_conf_editor/layouts.js @@ -0,0 +1,91 @@ +/* + Парус 8 - Панели мониторинга - РО - Редактор настройки регламентированного отчёта + Дополнительная разметка и вёрстка клиентских элементов +*/ + +//--------------------- +//Подключение библиотек +//--------------------- + +import React from "react"; //Классы React +import { MarksToolbar } from "./components/marks_toolbar"; //Панель инструментов показателей +import { MarkCard } from "./components/mark_card"; //Карточка показателя +import { STYLES as COMMON_STYLES } from "./common"; //Общие стили и константы + +//--------- +//Константы +//--------- + +//Стили +export const STYLES = { + HEAD_CELL: { + textAlign: "center", + fontWeight: "bold", + lineHeight: "unset", + ...COMMON_STYLES.FONT_DATA_GRID, + ...COMMON_STYLES.BG_DATA_GRID_HEAD_CELL, + ...COMMON_STYLES.BORDER_DATA_GRID_HEAD_CELL + }, + HEAD_CELL_STACK: { justifyContent: "center" }, + DATA_CELL: isMarkRowHead => ({ + padding: "5px 5px", + textAlign: "center", + ...COMMON_STYLES.FONT_DATA_GRID, + ...(isMarkRowHead + ? { ...COMMON_STYLES.BG_DATA_GRID_DATA_CELL, ...COMMON_STYLES.BORDER_DATA_GRID_HEAD_CELL, fontWeight: "bold" } + : COMMON_STYLES.BORDER_DATA_GRID_DATA_CELL) + }) +}; + +//----------- +//Тело модуля +//----------- + +//Генерация представления ячейки c данными показателя раздела регламентированного отчета +export const confSctnMrkCellRender = ({ row, columnDef, onMarkAdd, onMarkUpdate, onMarkDelete, onMarkOpen, onMarkCnOpen, onMarkCnAdd }) => { + //Считываем информацию о показателе + const mark = { + rn: row[columnDef.name]?.NRN, + code: row[columnDef.name]?.SCODE, + name: row[columnDef.name]?.SNAME, + row: row[columnDef.name]?.NRRPROW, + rowCode: row[columnDef.name]?.SRRPROW, + rowVersion: row[columnDef.name]?.SRRPVERSION_ROW, + column: row[columnDef.name]?.NRRPCOLUMN, + columnCode: row[columnDef.name]?.SRRPCOLUMN, + columnVersion: row[columnDef.name]?.SRRPVERSION_COLUMN, + constitution: row[columnDef.name]?.CONSTITUTION + }; + //Вернём представление ячейки + return { + cellStyle: STYLES.DATA_CELL(columnDef.name === "SROW_NAME"), + data: columnDef.name != "SROW_NAME" && ( + onMarkAdd && onMarkAdd(mark.row, mark.column)} + onMarkUpdate={() => onMarkUpdate && onMarkUpdate({ ...mark })} + onMarkDelete={() => onMarkDelete && onMarkDelete(mark.rn)} + onMarkOpen={() => onMarkOpen && onMarkOpen(mark.rn)} + onMarkCnOpen={constitutionRn => onMarkCnOpen && onMarkCnOpen(mark.rn, constitutionRn)} + onMarkCnAdd={() => onMarkCnAdd && onMarkCnAdd(mark.rn)} + /> + ) + }; +}; + +//Генерация представления ячейки заголовка таблицы показателей +export const confSctnMrkHeadCellRender = ({ columnDef, onAdd, onRefresh, onOrder, onHelp }) => { + return { + cellStyle: STYLES.HEAD_CELL, + stackStyle: STYLES.HEAD_CELL_STACK, + data: + columnDef.name === "SROW_NAME" ? ( + + ) : ( + columnDef.caption + ) + }; +}; diff --git a/app/panels/rrp_conf_editor/rrp_conf_editor.js b/app/panels/rrp_conf_editor/rrp_conf_editor.js index f86e797..3949cd3 100644 --- a/app/panels/rrp_conf_editor/rrp_conf_editor.js +++ b/app/panels/rrp_conf_editor/rrp_conf_editor.js @@ -7,32 +7,23 @@ //Подключение библиотек //--------------------- -import React, { useState, useEffect } from "react"; //Классы React -import { Box, Tab, Tabs, IconButton, Icon, Stack } from "@mui/material"; //Интерфейсные компоненты -import { IUDFormDialog } from "./IUD/iud_form_dialog"; //Диалог добавления/исправления/удаления компонентов настройки регламентированного отчёта -import { useWindowResize, useTab, useConf, useRecOpen, useFormDialog, a11yProps } from "./hooks"; //Пользовательские хуки -import { SectionTab } from "./components/rrp_section"; //Компонент раздела настройки +import React, { useState, useEffect, useContext } from "react"; //Классы React +import { Grid } from "@mui/material"; //Интерфейсные компоненты +import { APP_BAR_HEIGHT } from "../../components/p8p_app_workspace"; //Рабочая область приложения +import { NavigationCtx } from "../../context/navigation"; //Контекст навигации +import { Sections } from "./components/sections"; //Список разделов настройки +import { Section } from "./components/section"; //Раздел настройки //--------- //Константы //--------- -//Высота меню Парус (пиксели) -const pxOuterMenuH = 53; -//Высота заголовка панели (пиксели) -const pxPanelHeaderH = 64; -//Ширина кнопки добавления раздела (пиксели) -const pxSectionAddButtonW = 40; - //Стили const STYLES = { - CONTAINER: { width: "100%", minHeight: `calc(100vh - ${pxPanelHeaderH})`, maxHeight: `calc(100vh - ${pxPanelHeaderH})` }, - PANELS_MAIN_COLOR: { backgroundColor: "#1976d2" }, - ICON_WHITE: { color: "white" }, - TABS_BOTTOM_LINE: { borderBottom: 1, borderColor: "divider" }, - TABS_PADDING: { padding: "5px" }, - TABS_SIZES: (width, pxSectionAddButtonW) => ({ maxHeight: 150, maxWidth: width - pxSectionAddButtonW }), - SECTION_ACTIONS: { display: "flex", justifyContent: "center", alignItems: "center" } + GRID_MAIN_CONTAINER: { height: `calc(100vh - ${APP_BAR_HEIGHT})` }, + GRID_MAIN_SECTIONS_ITEM: fullHeight => ({ ...(fullHeight ? { height: "100%" } : {}) }), + GRID_SECTIONS_CONTAINER: { width: "100vw", height: "100%" }, + GRID_SECTION_CONTAINER: { height: "100%" } }; //----------- @@ -41,122 +32,46 @@ const STYLES = { //Редактор настройки регламентированного отчёта const RrpConfEditor = () => { - //Состояние вкладки - const [tabValue, handleSectionChange] = useTab(""); + //Редактируемая настройка + const [conf, setConf] = useState(null); - //Состояние сортировки строк и граф - const [order, setOrder] = useState({ rowOrder: 0, columnOrder: 0 }); + //Текущий раздел настройки + const [section, setSection] = useState(null); - //Изменение состояния сортировки строк и граф - const handleOrder = newOrder => setOrder(newOrder); + //Текущее количество разделов настройки + const [sectionsCount, setSectionsCount] = useState(0); - //Состояние настройки - const [rrpConf, handleReload] = useConf(tabValue, handleSectionChange, order); + //Подключение к контексту навигации + const { getNavigationSearch } = useContext(NavigationCtx); - //Функции открытия разделов - const [handleMarkOpen, handleMarkCnOpen, handleMarkCnInsert] = useRecOpen(handleReload); + //Изменение текущего раздела настройки + const handleSectionChange = section => setSection(section); - //Состояние форм диалога - const [ - formOpen, - formData, - handleSectionAdd, - handleSectionEdit, - handleSectionDelete, - handleMarkAdd, - handleMarkEdit, - handleMarkDelete, - handleDialogClose - ] = useFormDialog(); + //Изменение количества разделов настройки + const handleSectionsCountChange = sectionsCount => setSectionsCount(sectionsCount); - //Состояние ширины и высоты рабочей области окна - const [width, height] = useWindowResize(); - - //Состояние высоты вкладок с разделами - const [pxTabsH, setPxTabsH] = useState(0); - - //При рендере данных + //При подключении к странице useEffect(() => { - rrpConf.docLoaded ? setPxTabsH(document.getElementById("sectionTabs").offsetHeight) : null; - }, [rrpConf.docLoaded]); - - //Формируем меню показателей - const markMenuItems = [ - { method: "EDIT", name: "Исправить", icon: "edit", func: handleMarkEdit }, - { method: "DELETE", name: "Удалить", icon: "delete", func: handleMarkDelete } - ]; + setConf(Number(getNavigationSearch().NRN)); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); //Генерация содержимого return ( - - {formOpen ? : null} - {rrpConf.docLoaded ? ( - - - handleSectionChange(newValue)} - variant="scrollable" - scrollButtons={false} - visibleScrollbar - aria-label="section tab" - sx={STYLES.TABS_SIZES(width, pxSectionAddButtonW)} - > - {rrpConf.sections.map((s, i) => { - return ( - - {s.name} - handleSectionEdit(s.rn, s.code, s.name)}> - edit - - handleSectionDelete(s.rn, s.code, s.name)} - > - delete - - - } - wrapped - /> - ); - })} - - - - add - - - - {rrpConf.sections.map((s, i) => { - return ( - - ); - })} - - ) : null} - + + + + + + + {sectionsCount > 0 && ( + + +
+ + + )} + ); }; diff --git a/db/PKG_P8PANELS_RRPCONFED.pck b/db/PKG_P8PANELS_RRPCONFED.pck index 6c9ef47..ba73533 100644 --- a/db/PKG_P8PANELS_RRPCONFED.pck +++ b/db/PKG_P8PANELS_RRPCONFED.pck @@ -1,12 +1,45 @@ create or replace package PKG_P8PANELS_RRPCONFED as - /* Получение разделов регламентированного отчёта */ - procedure RRPCONF_GET_SECTIONS + /* Добавление показателя раздела регламентированного отчёта */ + procedure RRPCONFSCTNMRK_INSERT ( - NRN_RRPCONF in number, -- Рег. номер настройки форм регламентированного отчёта - NROW_ORDER in number := 0, -- Порядок сортировки строк - NCOL_ORDER in number := 0, -- Порядок сортировки граф - COUT out clob -- Список разделов + NPRN in number, -- Рег. номер раздела + SCODE in varchar2, -- Мнемокод показателя раздела + SNAME in varchar2, -- Наименование показателя раздела + NRRPROW in number, -- Рег. номер строки + SRRPROW in varchar2, -- Код строки (игнорируется, если указан рег. номер строки) + SRRPVERSION_ROW in varchar2, -- Код редакции строки (игнорируется, если указан рег. номер строки) + NRRPCOLUMN in number, -- Рег. номер графы + SRRPCOLUMN in varchar2, -- Код графы + SRRPVERSION_COLUMN in varchar2, -- Код редакции графы + NRN out number -- Рег. номер созданной записи + ); + + /* Исправление показателя раздела регламентированного отчёта */ + procedure RRPCONFSCTNMRK_UPDATE + ( + NRN in number, -- Рег. номер показателя раздела + SCODE in varchar2, -- Мнемокод показателя раздела + SNAME in varchar2, -- Наименование показателя раздела + SRRPROW in varchar2, -- Код строки + SRRPVERSION_ROW in varchar2, -- Код редакции строки + SRRPCOLUMN in varchar2, -- Код графы + SRRPVERSION_COLUMN in varchar2 -- Код редакции графы + ); + + /* Удаление показателя раздела регламентированного отчёта */ + procedure RRPCONFSCTNMRK_DELETE + ( + NRN in number -- Рег. номер показателя раздела + ); + + /* Получение раздела регламентированного отчёта */ + procedure RRPCONFSCTN_GET + ( + NRRPCONFSCTN in number, -- Рег. номер раздела настройки форм регламентированного отчёта + NROW_ORDER in number := 0, -- Порядок сортировки строк (0 - по номеру, 1 - по коду, 2 - по мнемокоду) + NCOL_ORDER in number := 0, -- Порядок сортировки граф (0 - по номеру, 1 - по коду, 2 - по мнемокоду) + COUT out clob -- Данные раздела ); /* Добавление раздела регламентированного отчёта */ @@ -32,61 +65,24 @@ create or replace package PKG_P8PANELS_RRPCONFED as NRN in number -- Рег. номер раздела ); - /* Получение кодов настройки, раздела и показателя раздела по ид. показателя раздела */ - procedure RRPCONFSCTNMRK_GET_CODES + /* Получение описания настройки регламентированного отчета */ + procedure RRPCONF_GET ( - NRN in number, -- Рег. номер показателя раздела - SRRPCONF out varchar2, -- Мнемокод настройки формы регламентированного отчёта - SRRPCONFSCTN out varchar2, -- Мнемокод раздела - SRRPCONFSCTNMRK out varchar2 -- Мнемокод показателя раздела - ); - - /* Формирование кода и наименования показателя раздела регламентированного отчёта */ - procedure RRPCONFSCTNMRK_GET_CODE_NAME - ( - NRRPCONFSCTN in number, -- Рег. номер раздела - NRRPROW in number, -- Рег. номер строки - NRRPCOLUMN in number, -- Рег. номер графы - SCODE out varchar2, -- Мнемокод показателя раздела - SNAME out varchar2 -- Наименование показателя раздела - ); - - /* Формирование кода и наименования показателя раздела регламентированного отчёта */ - procedure RRPCONFSCTNMRK_GET_NAME - ( - NRRPCONFSCTNMRK in number, -- Рег. номер показателя - SNAME out varchar2 -- Наименование показателя раздела - ); - - /* Добавление показателя раздела регламентированного отчёта */ - procedure RRPCONFSCTNMRK_INSERT - ( - NPRN in number, -- Рег. номер раздела - SCODE in varchar2, -- Мнемокод показателя раздела - SNAME in varchar2, -- Наименование показателя раздела - NRRPROW in number, -- Рег. номер строки - NRRPCOLUMN in number, -- Рег. номер графы - NRN out number -- Рег. номер созданной записи - ); - - /* Исправление показателя раздела регламентированного отчёта */ - procedure RRPCONFSCTNMRK_UPDATE - ( - NRN in number, -- Рег. номер показателя раздела - SNAME in varchar2 -- Новое наименование - ); - - /* Удаление показателя раздела регламентированного отчёта */ - procedure RRPCONFSCTNMRK_DELETE - ( - NRN in number -- Рег. номер показателя раздела + NRRPCONF in number, -- Рег. номер настройки форм регламентированного отчёта + COUT out clob -- Описание настройки ); end PKG_P8PANELS_RRPCONFED; / create or replace package body PKG_P8PANELS_RRPCONFED as - /* Маски для формирования представления параметров состава показателя */ + /* Константы - общие параметры формирования данных */ + NSECTION_NAME_MAX_LEN constant PKG_STD.TNUMBER := 100; -- Максимальный отображаемый размер наименования раздела настройки (символов) + + /* Константы - параметры таблицы показателей раздела настройки РО */ + NMRKS_DG_COL_WIDTH constant PKG_STD.TNUMBER := 250; -- Ширина колонки (пикселей) + + /* Константы - маски для формирования представления параметров состава показателя */ SPRM_MASK_ACC_DC constant PKG_STD.TSTRING := 'ДЕБЕТ_КРЕДИТ'; -- Маска для параметров "Счет дебет" и "Счет кредит" SPRM_MASK_ACC constant PKG_STD.TSTRING := 'СЧЕТ'; -- Маска для параметров "Счет" SPRM_MASK_ACC_WO_ANL constant PKG_STD.TSTRING := 'СЧЕТ_БЕЗ_АНЛ'; -- Маска для параметров "Счет" без учета аналитик @@ -104,9 +100,10 @@ create or replace package body PKG_P8PANELS_RRPCONFED as /* Получение доступности действия раздела */ function UTL_UNIT_ACTION_GET_ALLOW ( + NCOMPANY in number, -- Рег. номер организации + NRN in number, -- Рег. номер записи SUNIT in varchar2, -- Мнемокод раздела (см. константы SUNIT_*) - SACTION in varchar2, -- Действие (см. константы SACTION_*) - NRN in number -- Рег. номер записи + SACTION in varchar2 -- Действие (см. константы SACTION_*) ) return number -- Доступность действия (0 - недоступно, 1 - доступно) is NRESULT PKG_STD.TNUMBER; -- Доступность действия (0 - недоступно, 1 - доступно) @@ -119,25 +116,20 @@ create or replace package body PKG_P8PANELS_RRPCONFED as case SACTION /* Удаление */ when SACTION_DELETE then - /* Если раздел есть в сформированном отчете/параметре отчета/имеет дочерний раздел - удаление невозможно */ begin - select 0 - into NRESULT - from DUAL - where exists (select null from RRPDOC_STORAGE_SCTN S where S.RRPCONFSCTN = NRN) - or exists (select null from RRPDOCPRM P where P.RRPCONFSCTN = NRN) - or exists (select null from RRPCONFSCTN C where C.RRPCONFSCTN = NRN); + /* Выполним типовую проверку */ + P_RRPCONFSCTN_BASE_CHECK(SMODE => 'D', + RREC => GET_RRPCONFSCTN_ID(NFLAG_SMART => 0, NCOMPANY => NCOMPANY, NRN => NRN)); + /* Проверка пройдена - можно удалять */ + NRESULT := 1; exception - /* Если таких записей нет - удаление возможно */ - when NO_DATA_FOUND then - NRESULT := 1; - /* Если необработанная ошибка - удаление невозможно */ + /* Если проверка выдала ошибку - удаление невозможно */ when others then NRESULT := 0; end; - /* Действие неопределено */ + /* Действие неопределено - нельзя выполнять */ else - NRESULT := 1; + NRESULT := 0; end case; /* Показатель раздела настройки регламентированного отчета */ when SUNIT_RRPCONFSCTNMRK then @@ -145,33 +137,106 @@ create or replace package body PKG_P8PANELS_RRPCONFED as case SACTION /* Удаление */ when SACTION_DELETE then - /* Если показатель есть в сформированном отчете - удаление невозможно */ begin - select 0 - into NRESULT - from DUAL - where exists (select null from RRPDOC_STORAGE_MRK M where M.RRPCONFSCTNMRK = NRN); + /* Выполним типовую проверку */ + P_RRPCONFSCTNMRK_BASE_CHECK(SMODE => 'D', + RREC => GET_RRPCONFSCTNMRK_ID(NFLAG_SMART => 0, + NCOMPANY => NCOMPANY, + NRN => NRN)); + /* Проверка пройдена - можно удалять */ + NRESULT := 1; exception - /* Если таких записей нет - удаление возможно */ - when NO_DATA_FOUND then - NRESULT := 1; - /* Если необработанная ошибка - удаление невозможно */ + /* Если проверка выдала ошибку - удаление невозможно */ when others then NRESULT := 0; end; - else - NRESULT := 1; + /* Действие неопределено - нельзя выполнять */ + else + NRESULT := 0; end case; - /* Раздел неопределен */ + /* Раздел неопределен - нельзя делать */ else - NRESULT := 1; + NRESULT := 0; end case; /* Возвращаем результат */ return NRESULT; end UTL_UNIT_ACTION_GET_ALLOW; + + /* Считывание типа источинка состава показателя в текстовом представлении */ + function RRPCONFSCTNMRKCN_GET_ST + ( + NSOURCE_TYPE in number, -- Тип источника + SSOURCE_UNIT in varchar2 -- Раздел источника + ) return varchar2 -- Тип источника в текстовом представлении + is + SRESULT PKG_STD.TSTRING; -- Тип источника в текстовом представлении + begin + /* Строковое представление источника значения */ + case NSOURCE_TYPE + when 0 then + /* Исходим от раздела */ + case SSOURCE_UNIT + when 'EconomicOperations' then + SRESULT := 'ХО'; + when 'DebitorsCreditorsAccounts' then + SRESULT := 'РСДК'; + when 'AccountsRemnants' then + SRESULT := 'ОС'; + when 'ValuesRemnants' then + SRESULT := 'ТМЦ'; + when 'DebitorsCreditorsRemnants' then + SRESULT := 'ДКЗ'; + when 'Inventory' then + SRESULT := 'ИК'; + when 'ItemsCards' then + SRESULT := 'МБП'; + when 'OperCards' then + SRESULT := 'КОБП'; + when 'DeclarationIncome' then + SRESULT := 'ДПНП'; + when 'RRPDocuments' then + SRESULT := 'РО'; + else + SRESULT := null; + end case; + when 1 then + SRESULT := 'РП'; + when 2 then + SRESULT := 'ХП'; + when 3 then + SRESULT := 'СЗ'; + when 4 then + SRESULT := 'fx'; + else + SRESULT := null; + end case; + /* Возвращаем результат */ + return SRESULT; + end RRPCONFSCTNMRKCN_GET_ST; + + /* Считывание знака состава показателя в текстовом представлении */ + function RRPCONFSCTNMRKCN_GET_SIGN + ( + NSIGN in number -- Знак состава показателя + ) return varchar2 -- Знак состава показателя в текстовом представлении + is + SRESULT PKG_STD.TSTRING; -- Знак состава показателя в текстовом представлении + begin + /* Опеределяем знак */ + case NSIGN + when 0 then + SRESULT := '+'; + when 1 then + SRESULT := '-'; + else + SRESULT := '+/-'; + end case; + /* Возвращаем результат */ + return SRESULT; + end RRPCONFSCTNMRKCN_GET_SIGN; /* Формирование описателя состава показателя регламентированного отчета */ - function UTL_RRPCONFSCTNMRKCN_GET_DESC + function RRPCONFSCTNMRKCN_GET_DESC ( NCOMPANY in number, -- Рег. номер организации NRRPCONFSCTNMRKCN in number -- Рег. номер состава показателя регламентированного отчета @@ -183,7 +248,7 @@ create or replace package body PKG_P8PANELS_RRPCONFED as RRRPCONFSCTNMRK RRPCONFSCTNMRK%rowtype; -- Запись показателя регламентированного отчета /* Считывание мнемокода показателя по рег. номеру состава показателя */ - function UTL_MARK_GET_CODE_BY_CN + function MARK_GET_CODE_BY_CN ( NRRPCONFSCTNMRKCN in number -- Рег. номер состава показателя ) return varchar2 -- Мнемокод показателя @@ -204,10 +269,10 @@ create or replace package body PKG_P8PANELS_RRPCONFED as end; /* Возвращаем результат */ return SRESULT; - end UTL_MARK_GET_CODE_BY_CN; + end MARK_GET_CODE_BY_CN; /* Считывание мнемокода настройки по рег. номеру состава показателя */ - function UTL_CONF_GET_CODE_BY_CN + function CONF_GET_CODE_BY_CN ( NRRPCONFSCTNMRKCN in number -- Рег. номер состава показателя ) return varchar2 -- Мнемокод настройки регламентированного отчета @@ -230,47 +295,47 @@ create or replace package body PKG_P8PANELS_RRPCONFED as end; /* Возвращаем результат */ return SRESULT; - end UTL_CONF_GET_CODE_BY_CN; + end CONF_GET_CODE_BY_CN; /* Формирование представления параметров состава показателя */ procedure MAKE_PRMS_BY_MASK ( - SPRMS_DESC in out varchar2, -- Строковое представление параметров - NCOMPANY in number, -- Рег. номер организации - NRRPCONFSCTNMRKCN in number, -- Рег. номер состава показателя - SMASK in varchar2 -- Маска (см. константы SPRM_MASK_*) + SPRMS_DESC in out varchar2, -- Строковое представление параметров + NCOMPANY in number, -- Рег. номер организации + NRRPCONFSCTNMRKCN in number, -- Рег. номер состава показателя + SMASK in varchar2 -- Маска (см. константы SPRM_MASK_*) ) is - SDATE_FROM PKG_STD.TSTRING; -- Строковое представление "Дата с" - SDATE_TO PKG_STD.TSTRING; -- Строковое представление "Дата по" - DDATE_FROM PKG_STD.TLDATE; -- ДАТА_С - SDATE_FROM_PATTERN PKG_STD.TSTRING; -- ДАТА_С_ШАБЛОН - DDATE_TO PKG_STD.TLDATE; -- ДАТА_ПО - SDATE_TO_PATTERN PKG_STD.TSTRING; -- ДАТА_ПО_ШАБЛОН - SACCOUNT_DEBIT PKG_STD.TSTRING; -- СЧЕТ_ДЕБЕТ - SANALYTIC_DEBIT1 PKG_STD.TSTRING; -- АНАЛИТИКА1_ДЕБЕТ - SANALYTIC_DEBIT2 PKG_STD.TSTRING; -- АНАЛИТИКА2_ДЕБЕТ - SANALYTIC_DEBIT3 PKG_STD.TSTRING; -- АНАЛИТИКА3_ДЕБЕТ - SANALYTIC_DEBIT4 PKG_STD.TSTRING; -- АНАЛИТИКА4_ДЕБЕТ - SANALYTIC_DEBIT5 PKG_STD.TSTRING; -- АНАЛИТИКА5_ДЕБЕТ - SACCOUNT_CREDIT PKG_STD.TSTRING; -- СЧЕТ_КРЕДИТ - SANALYTIC_CREDIT1 PKG_STD.TSTRING; -- АНАЛИТИКА1_КРЕДИТ - SANALYTIC_CREDIT2 PKG_STD.TSTRING; -- АНАЛИТИКА2_КРЕДИТ - SANALYTIC_CREDIT3 PKG_STD.TSTRING; -- АНАЛИТИКА3_КРЕДИТ - SANALYTIC_CREDIT4 PKG_STD.TSTRING; -- АНАЛИТИКА4_КРЕДИТ - SANALYTIC_CREDIT5 PKG_STD.TSTRING; -- АНАЛИТИКА5_КРЕДИТ - SACCOUNT PKG_STD.TSTRING; -- СЧЕТ - SANALYTIC1 PKG_STD.TSTRING; -- АНАЛИТИКА1 - SANALYTIC2 PKG_STD.TSTRING; -- АНАЛИТИКА2 - SANALYTIC3 PKG_STD.TSTRING; -- АНАЛИТИКА3 - SANALYTIC4 PKG_STD.TSTRING; -- АНАЛИТИКА4 - SANALYTIC5 PKG_STD.TSTRING; -- АНАЛИТИКА5 - SRRPCONF PKG_STD.TSTRING; -- НАСТРОЙКА - NRRPCONF_RD PKG_STD.TNUMBER; -- НАСТРОЙКА_ТЕК - SMARK_CODE PKG_STD.TSTRING; -- ПОКАЗАТЕЛЬ - NMARK_CODE_RD PKG_STD.TNUMBER; -- ПОКАЗАТЕЛЬ_ТЕК - SMARK_ROW_CODE PKG_STD.TSTRING; -- СТРОКА_ПОКАЗАТЕЛЯ - SMARK_COL_CODE PKG_STD.TSTRING; -- ГРАФА_ПОКАЗАТЕЛЯ + SDATE_FROM PKG_STD.TSTRING; -- Строковое представление "Дата с" + SDATE_TO PKG_STD.TSTRING; -- Строковое представление "Дата по" + DDATE_FROM PKG_STD.TLDATE; -- ДАТА_С + SDATE_FROM_PATTERN PKG_STD.TSTRING; -- ДАТА_С_ШАБЛОН + DDATE_TO PKG_STD.TLDATE; -- ДАТА_ПО + SDATE_TO_PATTERN PKG_STD.TSTRING; -- ДАТА_ПО_ШАБЛОН + SACCOUNT_DEBIT PKG_STD.TSTRING; -- СЧЕТ_ДЕБЕТ + SANALYTIC_DEBIT1 PKG_STD.TSTRING; -- АНАЛИТИКА1_ДЕБЕТ + SANALYTIC_DEBIT2 PKG_STD.TSTRING; -- АНАЛИТИКА2_ДЕБЕТ + SANALYTIC_DEBIT3 PKG_STD.TSTRING; -- АНАЛИТИКА3_ДЕБЕТ + SANALYTIC_DEBIT4 PKG_STD.TSTRING; -- АНАЛИТИКА4_ДЕБЕТ + SANALYTIC_DEBIT5 PKG_STD.TSTRING; -- АНАЛИТИКА5_ДЕБЕТ + SACCOUNT_CREDIT PKG_STD.TSTRING; -- СЧЕТ_КРЕДИТ + SANALYTIC_CREDIT1 PKG_STD.TSTRING; -- АНАЛИТИКА1_КРЕДИТ + SANALYTIC_CREDIT2 PKG_STD.TSTRING; -- АНАЛИТИКА2_КРЕДИТ + SANALYTIC_CREDIT3 PKG_STD.TSTRING; -- АНАЛИТИКА3_КРЕДИТ + SANALYTIC_CREDIT4 PKG_STD.TSTRING; -- АНАЛИТИКА4_КРЕДИТ + SANALYTIC_CREDIT5 PKG_STD.TSTRING; -- АНАЛИТИКА5_КРЕДИТ + SACCOUNT PKG_STD.TSTRING; -- СЧЕТ + SANALYTIC1 PKG_STD.TSTRING; -- АНАЛИТИКА1 + SANALYTIC2 PKG_STD.TSTRING; -- АНАЛИТИКА2 + SANALYTIC3 PKG_STD.TSTRING; -- АНАЛИТИКА3 + SANALYTIC4 PKG_STD.TSTRING; -- АНАЛИТИКА4 + SANALYTIC5 PKG_STD.TSTRING; -- АНАЛИТИКА5 + SRRPCONF PKG_STD.TSTRING; -- НАСТРОЙКА + NRRPCONF_RD PKG_STD.TNUMBER; -- НАСТРОЙКА_ТЕК + SMARK_CODE PKG_STD.TSTRING; -- ПОКАЗАТЕЛЬ + NMARK_CODE_RD PKG_STD.TNUMBER; -- ПОКАЗАТЕЛЬ_ТЕК + SMARK_ROW_CODE PKG_STD.TSTRING; -- СТРОКА_ПОКАЗАТЕЛЯ + SMARK_COL_CODE PKG_STD.TSTRING; -- ГРАФА_ПОКАЗАТЕЛЯ begin /* Получаем представление параметров исходя из маски */ case SMASK @@ -435,7 +500,7 @@ create or replace package body PKG_P8PANELS_RRPCONFED as /* Если указана текущая настройка */ if (NRRPCONF_RD = 1) then /* Считываем мнемокод текущей настройки */ - SRRPCONF := UTL_CONF_GET_CODE_BY_CN(NRRPCONFSCTNMRKCN => NRRPCONFSCTNMRKCN); + SRRPCONF := CONF_GET_CODE_BY_CN(NRRPCONFSCTNMRKCN => NRRPCONFSCTNMRKCN); end if; /* Считывание значения - Мнемокод показателя */ SMARK_CODE := PKG_RRPCONFSCTNMRKCN.PARAM_GET_STR_VALUE(NCOMPANY => NCOMPANY, @@ -448,7 +513,7 @@ create or replace package body PKG_P8PANELS_RRPCONFED as /* Если указан текущий показатель */ if (NMARK_CODE_RD = 1) then /* Считываем мнемокод текущей настройки */ - SMARK_CODE := UTL_MARK_GET_CODE_BY_CN(NRRPCONFSCTNMRKCN => NRRPCONFSCTNMRKCN); + SMARK_CODE := MARK_GET_CODE_BY_CN(NRRPCONFSCTNMRKCN => NRRPCONFSCTNMRKCN); end if; /* Считывание значения - Мнемокод строки показателя */ SMARK_ROW_CODE := PKG_RRPCONFSCTNMRKCN.PARAM_GET_STR_VALUE(NCOMPANY => NCOMPANY, @@ -544,7 +609,7 @@ create or replace package body PKG_P8PANELS_RRPCONFED as NCOMPANY => NCOMPANY, NRRPCONFSCTNMRKCN => NRRPCONFSCTNMRKCN, SMASK => SPRM_MASK_DATE_FROM); - /* Остатки товарно-материальных ценностей */ + /* Остатки товарно-материальных ценностей */ when 'ValuesRemnants' then /* Получаем информацию по "Счет" */ MAKE_PRMS_BY_MASK(SPRMS_DESC => SRESULT, @@ -663,80 +728,7 @@ create or replace package body PKG_P8PANELS_RRPCONFED as SRESULT := SRESULT || ')'; /* Возвращаем результат */ return SRESULT; - end SOURCE_UNIT_GET_PRMS; - - /* Считывание типа источинка состава показателя в текстовом представлении */ - function RRPCONFSCTNMRKCN_GET_ST - ( - NSOURCE_TYPE in number, -- Тип источника - SSOURCE_UNIT in varchar2 -- Раздел источника - ) return varchar2 -- Тип источника в текстовом представлении - is - SRESULT PKG_STD.TSTRING; -- Тип источника в текстовом представлении - begin - /* Строковое представление источника значения */ - case NSOURCE_TYPE - when 0 then - /* Исходим от раздела */ - case SSOURCE_UNIT - when 'EconomicOperations' then - SRESULT := 'ХО'; - when 'DebitorsCreditorsAccounts' then - SRESULT := 'РСДК'; - when 'AccountsRemnants' then - SRESULT := 'ОС'; - when 'ValuesRemnants' then - SRESULT := 'ТМЦ'; - when 'DebitorsCreditorsRemnants' then - SRESULT := 'ДКЗ'; - when 'Inventory' then - SRESULT := 'ИК'; - when 'ItemsCards' then - SRESULT := 'МБП'; - when 'OperCards' then - SRESULT := 'КОБП'; - when 'DeclarationIncome' then - SRESULT := 'ДПНП'; - when 'RRPDocuments' then - SRESULT := 'РО'; - else - SRESULT := null; - end case; - when 1 then - SRESULT := 'РП'; - when 2 then - SRESULT := 'ХП'; - when 3 then - SRESULT := 'СЗ'; - when 4 then - SRESULT := 'fx'; - else - SRESULT := null; - end case; - /* Возвращаем результат */ - return SRESULT; - end RRPCONFSCTNMRKCN_GET_ST; - - /* Считывание знака состава показателя в текстовом представлении */ - function RRPCONFSCTNMRKCN_GET_SIGN - ( - NSIGN in number -- Знак состава показателя - ) return varchar2 -- Знак состава показателя в текстовом представлении - is - SRESULT PKG_STD.TSTRING; -- Знак состава показателя в текстовом представлении - begin - /* Опеределяем знак */ - case NSIGN - when 0 then - SRESULT := '+'; - when 1 then - SRESULT := '-'; - else - SRESULT := '+/-'; - end case; - /* Возвращаем результат */ - return SRESULT; - end RRPCONFSCTNMRKCN_GET_SIGN; + end SOURCE_UNIT_GET_PRMS; begin /* Считывание записи состава показателя регламентированного отчета */ RREC := GET_RRPCONFSCTNMRKCN_ID(NFLAG_SMART => 0, NCOMPANY => NCOMPANY, NRN => NRRPCONFSCTNMRKCN); @@ -775,62 +767,410 @@ create or replace package body PKG_P8PANELS_RRPCONFED as RRPCONFSCTNMRKCN_GET_ST(NSOURCE_TYPE => RREC.SOURCE_TYPE, SSOURCE_UNIT => RREC.SOURCE_UNIT) || SCN_DESC; /* Возвращаем результат */ return SRESULT; - end UTL_RRPCONFSCTNMRKCN_GET_DESC; - - /* Получение разделов регламентированного отчёта */ - procedure RRPCONF_GET_SECTIONS + end RRPCONFSCTNMRKCN_GET_DESC; + + /* Поиск рег. номера показателя по разделу РО/строке/графе */ + function RRPCONFSCTNMRK_GET_ROWCOL ( - NRN_RRPCONF in number, -- Рег. номер настройки форм регламентированного отчёта - NROW_ORDER in number := 0, -- Порядок сортировки строк - NCOL_ORDER in number := 0, -- Порядок сортировки граф - COUT out clob -- Список разделов + NRRPCONFSCTN in number, -- Рег. номер раздела + NRRPROW in number, -- Рег. номер строки + NRRPCOLUMN in number -- Рег. номер графы + ) return number -- Рег. номер показателя + is + NRESULT PKG_STD.TREF; -- Рег. номер показателя + begin + /* Считываем запись показателя */ + begin + select T.RN + into NRESULT + from RRPCONFSCTNMRK T + where T.PRN = NRRPCONFSCTN + and T.RRPROW = NRRPROW + and T.RRPCOLUMN = NRRPCOLUMN; + exception + when others then + NRESULT := null; + end; + /* Возвращаем результат */ + return NRESULT; + end RRPCONFSCTNMRK_GET_ROWCOL; + + /* Формирование описания показателя */ + function RRPCONFSCTNMRK_GET_DESC + ( + NCOMPANY in number, -- Рег. номер организации + NRRPCONFSCTN in number, -- Рег. номер раздела + NRRPROW in number, -- Рег. номер строки + NRRPCOLUMN in number -- Рег. номер графы + ) return varchar2 -- Сериализованное описание показателя + is + SRES PKG_STD.TLSTRING; -- Буфер для результата + NRRPCONFSCTNMRK PKG_STD.TREF; -- Рег. номер показателя настройки + begin + /* Найдём показатель */ + NRRPCONFSCTNMRK := RRPCONFSCTNMRK_GET_ROWCOL(NRRPCONFSCTN => NRRPCONFSCTN, + NRRPROW => NRRPROW, + NRRPCOLUMN => NRRPCOLUMN); + /* Начинаем формирование */ + PKG_XFAST.PROLOGUE(ITYPE => PKG_XFAST.CONTENT_); + /* Показатель */ + PKG_XFAST.DOWN_NODE(SNAME => 'XMARK'); + /* Атрибуты со сведениями о строке и графе */ + PKG_XFAST.ATTR(SNAME => 'NRRPROW', NVALUE => NRRPROW); + PKG_XFAST.ATTR(SNAME => 'NRRPCOLUMN', NVALUE => NRRPCOLUMN); + /* Обратимся к показателю */ + for MARK in (select T.RN NRN, + T.CODE SCODE, + T.NAME SNAME, + R.CODE SRRPROW, + RV.CODE SRRPVERSION_ROW, + C.CODE SRRPCOLUMN, + CV.CODE SRRPVERSION_COLUMN + from RRPCONFSCTNMRK T, + RRPROW R, + RRPCOLUMN C, + RRPVERSION RV, + RRPVERSION CV + where T.RN = NRRPCONFSCTNMRK + and T.RRPROW = R.RN + and T.RRPCOLUMN = C.RN + and R.RRPVERSION = RV.RN(+) + and C.RRPVERSION = CV.RN(+)) + loop + /* Атрибуты со сведениями о показателе */ + PKG_XFAST.ATTR(SNAME => 'NRN', NVALUE => MARK.NRN); + PKG_XFAST.ATTR(SNAME => 'SCODE', SVALUE => MARK.SCODE); + PKG_XFAST.ATTR(SNAME => 'SNAME', SVALUE => MARK.SNAME); + PKG_XFAST.ATTR(SNAME => 'SRRPROW', SVALUE => MARK.SRRPROW); + PKG_XFAST.ATTR(SNAME => 'SRRPVERSION_ROW', SVALUE => MARK.SRRPVERSION_ROW); + PKG_XFAST.ATTR(SNAME => 'SRRPCOLUMN', SVALUE => MARK.SRRPCOLUMN); + PKG_XFAST.ATTR(SNAME => 'SRRPVERSION_COLUMN', SVALUE => MARK.SRRPVERSION_COLUMN); + /* Цикл по составам показателей раздела */ + for CN in (select T.PRN, + T.RN, + T.NUMB + from RRPCONFSCTNMRKCN T + where T.PRN = NRRPCONFSCTNMRK + order by T.NUMB asc) + loop + /* Добавляем состав */ + PKG_XFAST.DOWN_NODE(SNAME => 'CONSTITUTION'); + PKG_XFAST.ATTR(SNAME => 'NPRN', NVALUE => CN.PRN); + PKG_XFAST.ATTR(SNAME => 'NRN', NVALUE => CN.RN); + PKG_XFAST.ATTR(SNAME => 'SNUMB', SVALUE => CN.NUMB); + PKG_XFAST.ATTR(SNAME => 'SDESC', + SVALUE => RRPCONFSCTNMRKCN_GET_DESC(NCOMPANY => NCOMPANY, NRRPCONFSCTNMRKCN => CN.RN)); + PKG_XFAST.UP(); + end loop; + end loop; + PKG_XFAST.UP(); + /* Сериализуем описание */ + SRES := PKG_XFAST.SERIALIZE_TO_VARCHAR(); + /* Завершаем формирование */ + PKG_XFAST.EPILOGUE(); + /* Возвращаем сформированное */ + return SRES; + end RRPCONFSCTNMRK_GET_DESC; + + /* Автоматическое формирование мнемокода и наименования показателя, если не указаны */ + procedure RRPCONFSCTNMRK_BUILD_CODE_NAME + ( + NCOMPANY in number, -- Рег. номер организации + NRRPCONFSCTN in number, -- Рег. номер раздела отчета + NRRPROW in number, -- Рег. номер строки показателя + NRRPCOLUMN in number, -- Рег. номер графы показателя + SCODE in out varchar2, -- Мнемокод показателя раздела (null - будет сформировано автоматически, иначе - вернётся без изменений) + SNAME in out varchar2 -- Наименование показателя раздела (null - будет сформировано автоматически, иначе - вернётся без изменений) + ) + is + RRRPCONFSCTN RRPCONFSCTN%rowtype; -- Запись раздела настройки + RRRPROW RRPROW%rowtype; -- Запись строки показателя + RRRPCOLUMN RRPCOLUMN%rowtype; -- Запись графы показателя + begin + /* Сформируем автоматический мнемокод, если пользователь не указал его */ + if (SCODE is null) then + /* Считаем указанные раздел, строку и графу */ + RRRPCONFSCTN := GET_RRPCONFSCTN_ID(NFLAG_SMART => 0, NCOMPANY => NCOMPANY, NRN => NRRPCONFSCTN); + RRRPROW := GET_RRPROW_ID(NFLAG_SMART => 0, NCOMPANY => NCOMPANY, NRN => NRRPROW); + RRRPCOLUMN := GET_RRPCOLUMN_ID(NFLAG_SMART => 0, NCOMPANY => NCOMPANY, NRN => NRRPCOLUMN); + /* Формируем мнемокод */ + P_RRPCONFSCTNMRK_MAKE_CODE(SRRPCONFSCTN => RRRPCONFSCTN.CODE, + SRRPROW => RRRPROW.CODE, + SRRPCOLUMN => RRRPCOLUMN.CODE, + SCODE => SCODE); + end if; + /* Сформируем автоматическое наименование, если пользователь не указал его */ + if (SNAME is null) then + P_RRPCONFSCTNMRK_MAKE_NAME(NCOMPANY => NCOMPANY, + NRRPROW => NRRPROW, + NRRPCOLUMN => NRRPCOLUMN, + NCHANGE_NAME => 1, + NCHANGE_NAME_PARENT => 0, + SNAME => SNAME); + end if; + end RRPCONFSCTNMRK_BUILD_CODE_NAME; + + /* Разыменовывание ссылок показателя, переданных пользователем */ + procedure RRPCONFSCTNMRK_JOINS + ( + NCOMPANY in number, -- Рег. номер организации + NRRPROW in number, -- Рег. номер строки + SRRPROW in varchar2, -- Код строки (игнорируется, если указан рег. номер строки) + SRRPVERSION_ROW in varchar2, -- Код редакции строки (игнорируется, если указан рег. номер строки) + NRRPCOLUMN in number, -- Рег. номер графы + SRRPCOLUMN in varchar2, -- Код графы (игнорируется, если указан рег. номер графы) + SRRPVERSION_COLUMN in varchar2, -- Код редакции графы (игнорируется, если указан рег. номер графы) + RRRPROW out RRPROW%rowtype, -- Запись строки регламентированного отчета + RRRPVERSION_ROW out RRPVERSION%rowtype, -- Запись редакции строки регламентированного отчета + RRRPCOLUMN out RRPCOLUMN%rowtype, -- Запись графы регламентированного отчета + RRRPVERSION_COLUMN out RRPVERSION%rowtype -- Запись редакции графы регламентированного отчета + ) + is + NRRPVERSION PKG_STD.TREF; -- Рег. номер редакции строки/графы + NRRPROW_ PKG_STD.TREF; -- Буфер для рег. номера строки + NRRPCOLUMN_ PKG_STD.TREF; -- Буфер для рег. номера графы + begin + /* Считываем запись строки и редакции строки регламентированного отчета */ + if (NRRPROW is null) then + FIND_RRPVERSION_CODE(NFLAG_SMART => 0, + NFLAG_OPTION => 1, + NCOMPANY => NCOMPANY, + SCODE => SRRPVERSION_ROW, + NRN => NRRPVERSION); + FIND_RRPROW_CODE(NFLAG_SMART => 0, + NFLAG_OPTION => 0, + NCOMPANY => NCOMPANY, + NRRPVERSION => NRRPVERSION, + SCODE => SRRPROW, + NRN => NRRPROW_); + else + NRRPROW_ := NRRPROW; + end if; + RRRPROW := GET_RRPROW_ID(NFLAG_SMART => 0, NCOMPANY => NCOMPANY, NRN => NRRPROW_); + RRRPVERSION_ROW := GET_RRPVERSION_ID(NFLAG_SMART => 1, NCOMPANY => NCOMPANY, NRN => RRRPROW.RRPVERSION); + /* Считываем запись графы и редакции графы регламентированного отчета */ + if (NRRPCOLUMN is null) then + FIND_RRPVERSION_CODE(NFLAG_SMART => 0, + NFLAG_OPTION => 1, + NCOMPANY => NCOMPANY, + SCODE => SRRPVERSION_COLUMN, + NRN => NRRPVERSION); + FIND_RRPCOLUMN_CODE(NFLAG_SMART => 0, + NFLAG_OPTION => 0, + NCOMPANY => NCOMPANY, + NRRPVERSION => NRRPVERSION, + SCODE => SRRPCOLUMN, + NRN => NRRPCOLUMN_); + else + NRRPCOLUMN_ := NRRPCOLUMN; + end if; + RRRPCOLUMN := GET_RRPCOLUMN_ID(NFLAG_SMART => 0, NCOMPANY => NCOMPANY, NRN => NRRPCOLUMN_); + RRRPVERSION_COLUMN := GET_RRPVERSION_ID(NFLAG_SMART => 1, NCOMPANY => NCOMPANY, NRN => RRRPCOLUMN.RRPVERSION); + end RRPCONFSCTNMRK_JOINS; + + /* Добавление показателя раздела регламентированного отчёта */ + procedure RRPCONFSCTNMRK_INSERT + ( + NPRN in number, -- Рег. номер раздела + SCODE in varchar2, -- Мнемокод показателя раздела + SNAME in varchar2, -- Наименование показателя раздела + NRRPROW in number, -- Рег. номер строки + SRRPROW in varchar2, -- Код строки (игнорируется, если указан рег. номер строки) + SRRPVERSION_ROW in varchar2, -- Код редакции строки (игнорируется, если указан рег. номер строки) + NRRPCOLUMN in number, -- Рег. номер графы + SRRPCOLUMN in varchar2, -- Код графы (игнорируется, если указан рег. номер графы) + SRRPVERSION_COLUMN in varchar2, -- Код редакции графы (игнорируется, если указан рег. номер графы) + NRN out number -- Рег. номер созданной записи + ) + is + NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Рег. номер организации + RRRPROW RRPROW%rowtype; -- Запись строки регламентированного отчета + RRRPVERSION_ROW RRPVERSION%rowtype; -- Запись редакции строки регламентированного отчета + RRRPCOLUMN RRPCOLUMN%rowtype; -- Запись графы регламентированного отчета + RRRPVERSION_COLUMN RRPVERSION%rowtype; -- Запись редакции графы регламентированного отчета + SCODE_ PKG_STD.TSTRING; -- Буфер для фактического мнемокода + SNAME_ PKG_STD.TSTRING; -- Буфер для фактического наименования + begin + /* Получим НСИ (строки, графы, редакции и т.п.) по данным, полученным от пользователя */ + RRPCONFSCTNMRK_JOINS(NCOMPANY => NCOMPANY, + NRRPROW => NRRPROW, + SRRPROW => SRRPROW, + SRRPVERSION_ROW => SRRPVERSION_ROW, + NRRPCOLUMN => NRRPCOLUMN, + SRRPCOLUMN => SRRPCOLUMN, + SRRPVERSION_COLUMN => SRRPVERSION_COLUMN, + RRRPROW => RRRPROW, + RRRPVERSION_ROW => RRRPVERSION_ROW, + RRRPCOLUMN => RRRPCOLUMN, + RRRPVERSION_COLUMN => RRRPVERSION_COLUMN); + /* Сформируем автоматические мнемокод и наименование, если пользователь не указал их */ + SCODE_ := SCODE; + SNAME_ := SNAME; + RRPCONFSCTNMRK_BUILD_CODE_NAME(NCOMPANY => NCOMPANY, + NRRPCONFSCTN => NPRN, + NRRPROW => RRRPROW.RN, + NRRPCOLUMN => RRRPCOLUMN.RN, + SCODE => SCODE_, + SNAME => SNAME_); + /* Добавим показатель */ + P_RRPCONFSCTNMRK_INSERT(NCOMPANY => NCOMPANY, + NPRN => NPRN, + NNUMB => F_RRPCONFSCTNMRK_NEXT_NUMB(NCOMPANY => NCOMPANY, NPRN => NPRN), + SCODE => SCODE_, + SNAME => SNAME_, + SRRPROW => RRRPROW.CODE, + SRRPVERSION_ROW => RRRPVERSION_ROW.CODE, + SRRPCOLUMN => RRRPCOLUMN.CODE, + SRRPVERSION_COLUMN => RRRPVERSION_COLUMN.CODE, + SPKG_ROW => null, + SPRC_ROW => null, + SPKG_COL => null, + SPRC_COL => null, + SRRPPRM => null, + NIGNORE_ZOOM => 0, + NIGNORE_SHARP => 0, + SCLSF_CODE => null, + SNOTE => null, + NDUP_RN => null, + NRN => NRN); + end RRPCONFSCTNMRK_INSERT; + + /* Исправление показателя раздела регламентированного отчёта */ + procedure RRPCONFSCTNMRK_UPDATE + ( + NRN in number, -- Рег. номер показателя раздела + SCODE in varchar2, -- Мнемокод показателя раздела + SNAME in varchar2, -- Наименование показателя раздела + SRRPROW in varchar2, -- Код строки + SRRPVERSION_ROW in varchar2, -- Код редакции строки + SRRPCOLUMN in varchar2, -- Код графы + SRRPVERSION_COLUMN in varchar2 -- Код редакции графы + ) + is + NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Рег. номер организации + RMRK RRPCONFSCTNMRK%rowtype; -- Запись настройки показателя регламентированного отчета + RRRPPRM RRPPRM%rowtype; -- Запись типового параметра регламентированного отчета + RRRPROW RRPROW%rowtype; -- Запись строки регламентированного отчета + RRRPVERSION_ROW RRPVERSION%rowtype; -- Запись редакции строки регламентированного отчета + RRRPCOLUMN RRPCOLUMN%rowtype; -- Запись графы регламентированного отчета + RRRPVERSION_COLUMN RRPVERSION%rowtype; -- Запись редакции графы регламентированного отчета + SCODE_ PKG_STD.TSTRING; -- Буфер для фактического мнемокода + SNAME_ PKG_STD.TSTRING; -- Буфер для фактического наименования + begin + /* Получение записи параметра раздела */ + RMRK := GET_RRPCONFSCTNMRK_ID(NFLAG_SMART => 0, NCOMPANY => NCOMPANY, NRN => NRN); + /* Получим НСИ (строки, графы, редакции и т.п.) по данным, полученным от пользователя */ + RRPCONFSCTNMRK_JOINS(NCOMPANY => NCOMPANY, + NRRPROW => null, + SRRPROW => SRRPROW, + SRRPVERSION_ROW => SRRPVERSION_ROW, + NRRPCOLUMN => null, + SRRPCOLUMN => SRRPCOLUMN, + SRRPVERSION_COLUMN => SRRPVERSION_COLUMN, + RRRPROW => RRRPROW, + RRRPVERSION_ROW => RRRPVERSION_ROW, + RRRPCOLUMN => RRRPCOLUMN, + RRRPVERSION_COLUMN => RRRPVERSION_COLUMN); + /* Сформируем автоматические мнемокод и наименование, если пользователь не указал их */ + SCODE_ := SCODE; + SNAME_ := SNAME; + RRPCONFSCTNMRK_BUILD_CODE_NAME(NCOMPANY => NCOMPANY, + NRRPCONFSCTN => RMRK.PRN, + NRRPROW => RRRPROW.RN, + NRRPCOLUMN => RRRPCOLUMN.RN, + SCODE => SCODE_, + SNAME => SNAME_); + /* Считаем код типового параметра, если задан в показателе (чтобы не затереть существующий, т.к. пользователь нам его не передает сейчас) */ + if (RMRK.RRPPRM is not null) then + RRRPPRM := GET_RRPPRM_ID(NFLAG_SMART => 0, NCOMPANY => NCOMPANY, NRN => RMRK.RRPPRM); + else + RRRPPRM.CODE := null; + end if; + /* Исправим показатель */ + P_RRPCONFSCTNMRK_UPDATE(NRN => RMRK.RN, + NCOMPANY => NCOMPANY, + NNUMB => RMRK.NUMB, + SCODE => SCODE_, + SNAME => SNAME_, + SRRPROW => SRRPROW, + SRRPVERSION_ROW => SRRPVERSION_ROW, + SRRPCOLUMN => SRRPCOLUMN, + SRRPVERSION_COLUMN => SRRPVERSION_COLUMN, + SPKG_ROW => RMRK.PKG_ROW, + SPRC_ROW => RMRK.PRC_ROW, + SPKG_COL => RMRK.PKG_COL, + SPRC_COL => RMRK.PRC_COL, + SRRPPRM => RRRPPRM.CODE, + NIGNORE_ZOOM => RMRK.IGNORE_ZOOM, + NIGNORE_SHARP => RMRK.IGNORE_SHARP, + SCLSF_CODE => RMRK.CLSF_CODE, + NFORMULA_UPDATE => 1, + SNOTE => RMRK.NOTE); + end RRPCONFSCTNMRK_UPDATE; + + /* Удаление показателя раздела регламентированного отчёта */ + procedure RRPCONFSCTNMRK_DELETE + ( + NRN in number -- Рег. номер показателя раздела + ) + is + begin + /* Удалим показатель */ + P_RRPCONFSCTNMRK_DELETE(NCOMPANY => GET_SESSION_COMPANY(), NRN => NRN); + end RRPCONFSCTNMRK_DELETE; + + /* Получение раздела регламентированного отчёта */ + procedure RRPCONFSCTN_GET + ( + NRRPCONFSCTN in number, -- Рег. номер раздела настройки форм регламентированного отчёта + NROW_ORDER in number := 0, -- Порядок сортировки строк (0 - по номеру, 1 - по коду, 2 - по мнемокоду) + NCOL_ORDER in number := 0, -- Порядок сортировки граф (0 - по номеру, 1 - по коду, 2 - по мнемокоду) + COUT out clob -- Данные раздела ) is - NVERSION PKG_STD.TREF; -- Рег. номер версии словаря контрагентов NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса RDG PKG_P8PANELS_VISUAL.TDG; -- Описание таблицы - RDG_ROW PKG_P8PANELS_VISUAL.TDG_ROW; -- Строка таблицы - CDG clob; -- XML данных раздела - CXML PKG_CONTVALLOC2NS.TCONTAINER; -- Контейнер для данных XML - RRRPCONFSCTNMRK RRPCONFSCTNMRK%rowtype; -- Рег. номер показателя - NCURRENT_SECTION PKG_STD.TNUMBER; -- Идентификатор раздела настройки в контейнере - NSECTION_RN PKG_STD.TREF; -- Рег. номер раздел настройки - SSECTION_CODE PKG_STD.TSTRING; -- Мнемокод раздела настройки - SSECTION_NAME PKG_STD.TSTRING; -- Наименование раздела настройки - CSECTION_CLOB clob; -- Данные по разделу настройки - CSQL_ROWS clob; -- Запрос по строкам - SORDERS_R PKG_STD.TSTRING; -- Сортировка строк - ICURSOR_R integer; -- Курсор для исполнения запроса по строкам + RDG_ROW PKG_P8PANELS_VISUAL.TDG_ROW; -- Строка таблицы + ICURSOR integer; -- Курсор для исполнения запроса NROW_RN PKG_STD.TREF; -- Рег. номер строки - NROW_POS PKG_STD.TNUMBER := 0; -- Позиция строки - SROW_CODE PKG_STD.TSTRING; -- Код строки SROW_NAME PKG_STD.TSTRING; -- Наименование строки - CSQL_COLS clob; -- Запрос по графам - SORDERS_C PKG_STD.TSTRING; -- Сортировка граф - ICURSOR_C integer; -- Курсор для исполнения запроса по графам NCOL_RN PKG_STD.TREF; -- Рег. номер графы - SCOL_CODE PKG_STD.TSTRING; -- Код графы - SCOL_NAME PKG_STD.TSTRING; -- Наименование графы - /* Формирование текстового представления сортировки */ - function ORDER_TEXT_GET + /* Получение наименования колонки таблицы "Код" для строк/граф */ + function TABCOL_ROWCOL_CODE_GET ( - NORDER in number, -- Порядок сортировки - SALIAS in varchar2, -- Алиас таблицы - NTYPE in number -- Тип таблицы (0 - графы, 1 - строки) + STABLE in varchar2 -- Таблица (RRPROW - по строкам, RRPCOLUMN - по графам) + ) return varchar2 -- Наименование колонки таблицы для хранения "Кода" + is + begin + /* Смотрим от имени таблицы */ + if (STABLE = 'RRPCOLUMN') then + /* Код графы */ + return 'COLUMN_CODE'; + elsif (STABLE = 'RRPROW') then + /* Код строки */ + return 'ROW_CODE'; + else + /* Неизвестная таблица */ + P_EXCEPTION(0, + 'Таблица "%s" не поддерживается.', + COALESCE(STABLE, '<НЕ УКАЗАНА>')); + end if; + end TABCOL_ROWCOL_CODE_GET; + + /* Формирование условия сортировки для SQL-запроса по строкам/графам */ + function ORDER_CLAUSE_GET + ( + STABLE in varchar2, -- Таблица (RRPROW - по строкам, RRPCOLUMN - по графам) + NORDER in number, -- Порядок сортировки (0 - по номеру, 1 - по коду, 2 - по мнемокоду) + SALIAS in varchar2 -- Алиас таблицы в формируемом запросе ) return varchar2 -- Текстовое представление сортировки is SRESULT PKG_STD.TSTRING; -- Текстовое представление сортировки STABLE_COLUMN_CODE PKG_STD.TSTRING; -- Наименование колонки таблицы, содержащую код begin /* Определяем наименование колонки, содержающую код */ - if (NTYPE = 0) then - /* Код графы */ - STABLE_COLUMN_CODE := 'COLUMN_CODE'; - else - /* Код графы */ - STABLE_COLUMN_CODE := 'ROW_CODE'; - end if; + STABLE_COLUMN_CODE := TABCOL_ROWCOL_CODE_GET(STABLE => STABLE); /* Формируем представление сортировки */ case NORDER /* Код - номер сортировки - мнемокод */ @@ -848,366 +1188,170 @@ create or replace package body PKG_P8PANELS_RRPCONFED as end case; /* Возвращаем результат */ return SRESULT; - end ORDER_TEXT_GET; - - /* Инициализация колонок граф показателей */ - procedure MARKS_COLUMNS_INIT + end ORDER_CLAUSE_GET; + + /* Открытие курсора по строкам/графам раздела */ + procedure OPEN_ROWS_COLS_CUR ( - RDG in out nocopy PKG_P8PANELS_VISUAL.TDG, -- Описание таблицы - NRRPCONFSCTN in number, -- Рег. номер раздела - SORDER in varchar2 -- Сортировка - ) + NRRPCONFSCTN in number, -- Рег. номер раздела настройки форм регламентированного отчёта + STABLE in varchar2, -- Таблица (RRPROW - по строкам, RRPCOLUMN - по графам) + NORDER in number, -- Порядок сортировки (0 - по номеру, 1 - по коду, 2 - по мнемокоду) + ICURSOR in out integer -- Открытый курсор + ) is - CSQL clob; -- Запрос по графам показателей раздела - ICURSOR integer; -- Курсор для исполнения запроса по графам показателей раздела - SCOL_CODE PKG_STD.TSTRING; -- Мнемокод графы - SCOL_NAME PKG_STD.TSTRING; -- Наименование графы + CSQL clob; -- Запрос + SORDERS PKG_STD.TSTRING; -- Условия сортировки begin - /* Добавляем подсказку совместимости */ - CSQL := null; - CSQL := PKG_SQL_BUILD.COMPATIBLE(SSQL => CSQL); - PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => 'select C.CODE,'); - PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' C.NAME'); - PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from RRPCONFSCTNMRK T,'); - PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' RRPCOLUMN C'); - PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' where T.PRN = ' || NRRPCONFSCTN); - PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and T.RRPCOLUMN = C.RN'); - PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' group by C.RN,'); - PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' C.CODE,'); - PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' C.NAME,'); - PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' C.COLUMN_CODE,'); - PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' C.SORT_NUMB'); - PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' order by ' || SORDER); + /* Закроем курсор если открыт */ + if (PKG_SQL_DML.IS_OPEN(ICURSOR => ICURSOR)) then + PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR); + end if; + /* Определим условия сортировки */ + SORDERS := ORDER_CLAUSE_GET(STABLE => STABLE, NORDER => NORDER, SALIAS => 'T'); + /* Соберем запрос */ + CSQL := PKG_SQL_BUILD.COMPATIBLE(); + PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => 'select T.RN,'); + PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' T.NAME'); + PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' from RRPCONFSCTNMRK M,'); + PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' ' || STABLE || ' T'); + PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' where M.PRN = ' || TO_CHAR(NRRPCONFSCTN)); + PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' and T.RN = M.' || STABLE); + PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' group by T.RN,'); + PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' T.CODE,'); + PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' T.NAME,'); + PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' T.' || TABCOL_ROWCOL_CODE_GET(STABLE => STABLE) || ','); + PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' T.SORT_NUMB'); + PKG_SQL_BUILD.APPEND(SSQL => CSQL, SELEMENT1 => ' order by ' || SORDERS); /* Разбираем его */ ICURSOR := PKG_SQL_DML.OPEN_CURSOR(SWHAT => 'SELECT'); PKG_SQL_DML.PARSE(ICURSOR => ICURSOR, SQUERY => CSQL); /* Описываем структуру записи курсора */ - PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 1); + PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR, IPOSITION => 1); PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR, IPOSITION => 2); - /* Делаем выборку */ + /* Делаем выборку по курсору */ if (PKG_SQL_DML.EXECUTE(ICURSOR => ICURSOR) = 0) then null; end if; + end OPEN_ROWS_COLS_CUR; + + /* Формирование наименования колонки таблицы данных по рег. номеру графы показателя */ + function DG_COL_NAME_BY_RRPCOLUMN + ( + NRRPCOLUMN in number -- Рег. номер графы + ) return varchar2 -- Имя колонки для таблицы данных + is + begin + return 'SCOL_' || TO_CHAR(NRRPCOLUMN); + end DG_COL_NAME_BY_RRPCOLUMN; + + /* Получение рег. номера графы показателя по наименованию колонки таблицы данных */ + function RRPCOLUMN_BY_DG_COL_NAME + ( + SDG_COL_NAME in varchar2 -- Имя колонки таблицы данных + ) return number -- Рег. номер графы + is + begin + return TO_NUMBER(replace(SDG_COL_NAME, 'SCOL_', '')); + end RRPCOLUMN_BY_DG_COL_NAME; + + /* Инициализация колонок выходной таблицы */ + procedure COLUMNS_INIT + ( + RDG in out nocopy PKG_P8PANELS_VISUAL.TDG, -- Описание таблицы + NRRPCONFSCTN in number, -- Рег. номер раздела + NCOL_ORDER in number, -- Порядок сортировки граф (0 - по номеру, 1 - по коду, 2 - по мнемокоду) + NCOL_WIDTH in number -- Ширина колонки (пикселей) + ) + is + ICURSOR integer; -- Курсор для исполнения запроса по графам показателей раздела + NCOL_RN PKG_STD.TREF; -- Рег. номер графы + SCOL_NAME PKG_STD.TSTRING; -- Наименование графы + begin + /* Наименование строки будет отображаться в первой колонке */ + PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG, + SNAME => 'SROW_NAME', + SCAPTION => 'Наименование строки', + SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, + NWIDTH => NCOL_WIDTH); + /* Остальные колонки это графы настройки РО - строим запрос по графам показателей */ + OPEN_ROWS_COLS_CUR(NRRPCONFSCTN => NRRPCONFSCTN, STABLE => 'RRPCOLUMN', NORDER => NCOL_ORDER, ICURSOR => ICURSOR); /* Обходим графы показателей раздела */ while (PKG_SQL_DML.FETCH_ROWS(ICURSOR => ICURSOR) > 0) loop /* Считываем рег. номер строки */ - PKG_SQL_DML.COLUMN_VALUE_STR(ICURSOR => ICURSOR, IPOSITION => 1, SVALUE => SCOL_CODE); - /* Считываем код строки */ + PKG_SQL_DML.COLUMN_VALUE_NUM(ICURSOR => ICURSOR, IPOSITION => 1, NVALUE => NCOL_RN); + /* Считываем наименование строки */ PKG_SQL_DML.COLUMN_VALUE_STR(ICURSOR => ICURSOR, IPOSITION => 2, SVALUE => SCOL_NAME); /* Наименование графы */ PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG, - SNAME => 'SCOL_' || SCOL_CODE, + SNAME => DG_COL_NAME_BY_RRPCOLUMN(NRRPCOLUMN => NCOL_RN), SCAPTION => SCOL_NAME, SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, - NWIDTH => 200); - /* Рег. номер графы */ - PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG, - SNAME => 'NCOL_RN_' || SCOL_CODE, - SCAPTION => SCOL_NAME || ' рег. номер', - SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, - BVISIBLE => false); - /* Рег. номер показателя */ - PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG, - SNAME => 'NMARK_RN_' || SCOL_CODE, - SCAPTION => SCOL_NAME || ' рег. номер показателя', - SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, - BVISIBLE => false); - /* Мнемокод показателя */ - PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG, - SNAME => 'SMARK_CODE_' || SCOL_CODE, - SCAPTION => SCOL_NAME || ' мнемокод показателя', - SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, - BVISIBLE => false); - /* Для составов показтелей */ - PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG, - SNAME => 'MARK_CNS_' || SCOL_CODE, - SCAPTION => SCOL_NAME || ' состав показателя', - SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, - BVISIBLE => false); + NWIDTH => NCOL_WIDTH); end loop; /* Освобождаем курсор */ PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR); exception when others then - PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR); + if (PKG_SQL_DML.IS_OPEN(ICURSOR => ICURSOR)) then + PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR); + end if; raise; - end MARKS_COLUMNS_INIT; - - /* Считывание показателя по строке/графе */ - function RRPCONFSCTNMRK_GET_ROWCOL - ( - NRRPCONFSCTN in number, -- Рег. номер раздела - NRRPROW in number, -- Рег. номер строки - NRRPCOLUMN in number -- Рег. номер графы - ) return RRPCONFSCTNMRK%rowtype -- Запись показателя - is - RRESULT RRPCONFSCTNMRK%rowtype; -- Рег. номер показателя - begin - /* Считываем рег. номер показателя */ - begin - select T.* - into RRESULT - from RRPCONFSCTNMRK T - where T.PRN = NRRPCONFSCTN - and T.RRPROW = NRRPROW - and T.RRPCOLUMN = NRRPCOLUMN; - exception - when others then - RRESULT := null; - end; - /* Возвращаем результат */ - return RRESULT; - end RRPCONFSCTNMRK_GET_ROWCOL; + end COLUMNS_INIT; begin - /* Очистка контейнера */ - PKG_CONTVALLOC2NS.PURGE(RCONTAINER => CXML); - /* Определение версии раздела */ - NVERSION := GET_SESSION_VERSION(SUNITCODE => 'RRPConfig'); - /* Цикл по разделам настройки форм регламентированного отчёта */ - for S in (select T.RN NRN, - T.VERSION NVERSION, - T.CRN NCRN, - T.PRN NPRN, - T.CODE SCODE, - T.NAME SNAME, - COALESCE((select 1 - from RRPCONFSCTNMRK M - where M.PRN = T.RN - and ROWNUM = 1), - 0) NMARKS_EXISTS, - ROWNUM RNUM + /* Обращаемся к настройке */ + for S in (select T.RN NRN from RRPCONFSCTN T - where T.PRN = NRN_RRPCONF - and T.VERSION = NVERSION - order by T.CODE) + where T.RN = NRRPCONFSCTN + and exists (select null from RRPCONFSCTNMRK M where M.PRN = T.RN) + and exists (select null from V_USERPRIV UP where UP.CATALOG = T.CRN)) loop /* Инициализируем таблицу данных */ RDG := PKG_P8PANELS_VISUAL.TDG_MAKE(BFIXED_HEADER => true, NFIXED_COLUMNS => 1); - /* Наименование строки */ - PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG, - SNAME => 'SROW_NAME', - SCAPTION => '', - SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, - NWIDTH => 150); - /* Позиция строки */ - PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG, - SNAME => 'NROW_POS', - SCAPTION => 'Позиция строки', - SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, - BVISIBLE => false); - /* Мнемокод строки */ - PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG, - SNAME => 'SROW_CODE', - SCAPTION => 'Мнемокод строки', - SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, - BVISIBLE => false); - /* Рег. номер строки */ - PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG, - SNAME => 'NROW_RN', - SCAPTION => 'Рег. номер строки', - SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, - BVISIBLE => false); - /* Обнуляем счётчик позиции строки */ - NROW_POS := 0; - /* Если раздел содержит показатели */ - if (S.NMARKS_EXISTS = 1) then - /* Формируем текстовое представление сортировки графы */ - SORDERS_C := ORDER_TEXT_GET(NORDER => NCOL_ORDER, SALIAS => 'C', NTYPE => 0); - /* Инициализируем колонки граф */ - MARKS_COLUMNS_INIT(RDG => RDG, NRRPCONFSCTN => S.NRN, SORDER => SORDERS_C); - begin - /* Формируем текстовое представление сортировки строки */ - SORDERS_R := ORDER_TEXT_GET(NORDER => NROW_ORDER, SALIAS => 'R', NTYPE => 1); - /* Добавляем подсказку совместимости */ - CSQL_ROWS := PKG_SQL_BUILD.COMPATIBLE(); - PKG_SQL_BUILD.APPEND(SSQL => CSQL_ROWS, SELEMENT1 => 'select R.RN,'); - PKG_SQL_BUILD.APPEND(SSQL => CSQL_ROWS, SELEMENT1 => ' R.CODE,'); - PKG_SQL_BUILD.APPEND(SSQL => CSQL_ROWS, SELEMENT1 => ' R.NAME'); - PKG_SQL_BUILD.APPEND(SSQL => CSQL_ROWS, SELEMENT1 => ' from RRPCONFSCTNMRK T,'); - PKG_SQL_BUILD.APPEND(SSQL => CSQL_ROWS, SELEMENT1 => ' RRPROW R'); - PKG_SQL_BUILD.APPEND(SSQL => CSQL_ROWS, SELEMENT1 => ' where T.PRN = ' || S.NRN); - PKG_SQL_BUILD.APPEND(SSQL => CSQL_ROWS, SELEMENT1 => ' and R.RN = T.RRPROW'); - PKG_SQL_BUILD.APPEND(SSQL => CSQL_ROWS, SELEMENT1 => ' group by R.RN,'); - PKG_SQL_BUILD.APPEND(SSQL => CSQL_ROWS, SELEMENT1 => ' R.CODE,'); - PKG_SQL_BUILD.APPEND(SSQL => CSQL_ROWS, SELEMENT1 => ' R.NAME,'); - PKG_SQL_BUILD.APPEND(SSQL => CSQL_ROWS, SELEMENT1 => ' R.ROW_CODE,'); - PKG_SQL_BUILD.APPEND(SSQL => CSQL_ROWS, SELEMENT1 => ' R.SORT_NUMB'); - PKG_SQL_BUILD.APPEND(SSQL => CSQL_ROWS, SELEMENT1 => ' order by ' || SORDERS_R); - /* Разбираем его */ - ICURSOR_R := PKG_SQL_DML.OPEN_CURSOR(SWHAT => 'SELECT'); - PKG_SQL_DML.PARSE(ICURSOR => ICURSOR_R, SQUERY => CSQL_ROWS); - /* Описываем структуру записи курсора */ - PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR_R, IPOSITION => 1); - PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR_R, IPOSITION => 2); - PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR_R, IPOSITION => 3); - /* Делаем выборку */ - if (PKG_SQL_DML.EXECUTE(ICURSOR => ICURSOR_R) = 0) then - null; - end if; - /* Обходим выбранные записи */ - while (PKG_SQL_DML.FETCH_ROWS(ICURSOR => ICURSOR_R) > 0) - loop - /* Считываем рег. номер строки */ - PKG_SQL_DML.COLUMN_VALUE_NUM(ICURSOR => ICURSOR_R, IPOSITION => 1, NVALUE => NROW_RN); - /* Считываем код строки */ - PKG_SQL_DML.COLUMN_VALUE_STR(ICURSOR => ICURSOR_R, IPOSITION => 2, SVALUE => SROW_CODE); - /* Считываем наименование строки */ - PKG_SQL_DML.COLUMN_VALUE_STR(ICURSOR => ICURSOR_R, IPOSITION => 3, SVALUE => SROW_NAME); - /* Заполняем наименование строки */ - PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, - SNAME => 'SROW_NAME', - SVALUE => SROW_NAME, - BCLEAR => true); - /* Заполняем позицию строки */ - PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NROW_POS', NVALUE => NROW_POS); - /* Заполняем мнемокод строки */ - PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SROW_CODE', SVALUE => SROW_CODE); - /* Заполняем рег. номер строки */ - PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NROW_RN', NVALUE => NROW_RN); - /* Добавляем подсказку совместимости */ - CSQL_COLS := PKG_SQL_BUILD.COMPATIBLE(); - PKG_SQL_BUILD.APPEND(SSQL => CSQL_COLS, SELEMENT1 => 'select C.RN,'); - PKG_SQL_BUILD.APPEND(SSQL => CSQL_COLS, SELEMENT1 => ' C.CODE,'); - PKG_SQL_BUILD.APPEND(SSQL => CSQL_COLS, SELEMENT1 => ' C.NAME'); - PKG_SQL_BUILD.APPEND(SSQL => CSQL_COLS, SELEMENT1 => ' from RRPCONFSCTNMRK T,'); - PKG_SQL_BUILD.APPEND(SSQL => CSQL_COLS, SELEMENT1 => ' RRPCOLUMN C'); - PKG_SQL_BUILD.APPEND(SSQL => CSQL_COLS, SELEMENT1 => ' where T.PRN = ' || S.NRN); - PKG_SQL_BUILD.APPEND(SSQL => CSQL_COLS, SELEMENT1 => ' and C.RN = T.RRPCOLUMN'); - PKG_SQL_BUILD.APPEND(SSQL => CSQL_COLS, SELEMENT1 => ' group by C.RN,'); - PKG_SQL_BUILD.APPEND(SSQL => CSQL_COLS, SELEMENT1 => ' C.CODE,'); - PKG_SQL_BUILD.APPEND(SSQL => CSQL_COLS, SELEMENT1 => ' C.NAME,'); - PKG_SQL_BUILD.APPEND(SSQL => CSQL_COLS, SELEMENT1 => ' C.COLUMN_CODE,'); - PKG_SQL_BUILD.APPEND(SSQL => CSQL_COLS, SELEMENT1 => ' C.SORT_NUMB'); - PKG_SQL_BUILD.APPEND(SSQL => CSQL_COLS, SELEMENT1 => ' order by ' || SORDERS_C); - /* Разбираем его */ - ICURSOR_C := PKG_SQL_DML.OPEN_CURSOR(SWHAT => 'SELECT'); - PKG_SQL_DML.PARSE(ICURSOR => ICURSOR_C, SQUERY => CSQL_COLS); - /* Описываем структуру записи курсора */ - PKG_SQL_DML.DEFINE_COLUMN_NUM(ICURSOR => ICURSOR_C, IPOSITION => 1); - PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR_C, IPOSITION => 2); - PKG_SQL_DML.DEFINE_COLUMN_STR(ICURSOR => ICURSOR_C, IPOSITION => 3); - /* Делаем выборку */ - if (PKG_SQL_DML.EXECUTE(ICURSOR => ICURSOR_C) = 0) then - null; - end if; - /* Обходим выбранные записи */ - while (PKG_SQL_DML.FETCH_ROWS(ICURSOR => ICURSOR_C) > 0) - loop - /* Считываем рег. номер графы */ - PKG_SQL_DML.COLUMN_VALUE_NUM(ICURSOR => ICURSOR_C, IPOSITION => 1, NVALUE => NCOL_RN); - /* Считываем код графы */ - PKG_SQL_DML.COLUMN_VALUE_STR(ICURSOR => ICURSOR_C, IPOSITION => 2, SVALUE => SCOL_CODE); - /* Считываем наименование графы */ - PKG_SQL_DML.COLUMN_VALUE_STR(ICURSOR => ICURSOR_C, IPOSITION => 3, SVALUE => SCOL_NAME); - /* Считываем показатель по строке/графе */ - RRRPCONFSCTNMRK := RRPCONFSCTNMRK_GET_ROWCOL(NRRPCONFSCTN => S.NRN, - NRRPROW => NROW_RN, - NRRPCOLUMN => NCOL_RN); - /* Заполняем наименование графы */ - PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SCOL_' || SCOL_CODE, SVALUE => SCOL_NAME); - /* Заполняем рег. номер графы */ - PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NCOL_RN_' || SCOL_CODE, NVALUE => NCOL_RN); - /* Заполняем рег. номер показателя */ - PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, - SNAME => 'NMARK_RN_' || SCOL_CODE, - NVALUE => RRRPCONFSCTNMRK.RN); - /* Если ошибка считывания показателя */ - if (RRRPCONFSCTNMRK.RN is not null) then - /* Заполняем мнемокод показателя */ - PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, - SNAME => 'SMARK_CODE_' || SCOL_CODE, - SVALUE => RRRPCONFSCTNMRK.CODE); - /* Добавляем атрибут состава показателей */ - PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'MARK_CNS_' || SCOL_CODE, SVALUE => null); - end if; - end loop; - /* Освобождаем курсор */ - PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR_C); - /* Добавим строку для раздела */ - PKG_P8PANELS_VISUAL.TDG_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW); - /* Инкрементируем счётчик позиции строки */ - NROW_POS := NROW_POS + 1; - end loop; - /* Освобождаем курсор */ - PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR_R); - exception - when others then - PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR_R); - PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR_C); - raise; - end; - end if; - /* Сериализуем описание */ - CDG := PKG_P8PANELS_VISUAL.TDG_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => 1); - /* Заполняем контейнер данными о разделе */ - PKG_CONTVALLOC2NS.PUTN(RCONTAINER => CXML, NTABID => S.RNUM, SROWID => 'RN', NVALUE => S.NRN); - PKG_CONTVALLOC2NS.PUTS(RCONTAINER => CXML, NTABID => S.RNUM, SROWID => 'CODE', SVALUE => S.SCODE); - PKG_CONTVALLOC2NS.PUTS(RCONTAINER => CXML, NTABID => S.RNUM, SROWID => 'NAME', SVALUE => S.SNAME); - PKG_CONTVALLOC2NS.PUTLC(RCONTAINER => CXML, NTABID => S.RNUM, SROWID => 'CLOB', LCVALUE => CDG); - end loop; - /* Формируем XML с данными */ - PKG_XFAST.PROLOGUE(ITYPE => PKG_XFAST.CONTENT_); - PKG_XFAST.DOWN_NODE(SNAME => 'DATA'); - /* Цикл по контейнеру с данными о разделах */ - for X in 1 .. PKG_CONTVALLOC2NS.COUNT_(RCONTAINER => CXML) - loop - /* Ид. раздела */ - if (X = 1) then - NCURRENT_SECTION := PKG_CONTVALLOC2NS.FIRST_(RCONTAINER => CXML); - else - NCURRENT_SECTION := PKG_CONTVALLOC2NS.NEXT_(RCONTAINER => CXML, NTABID => NCURRENT_SECTION); - end if; - /* Рег. номер раздела */ - NSECTION_RN := PKG_CONTVALLOC2NS.GETN(RCONTAINER => CXML, NTABID => NCURRENT_SECTION, SROWID => 'RN'); - /* Мнемокод раздела */ - SSECTION_CODE := PKG_CONTVALLOC2NS.GETS(RCONTAINER => CXML, NTABID => NCURRENT_SECTION, SROWID => 'CODE'); - /* Наименование раздела */ - SSECTION_NAME := PKG_CONTVALLOC2NS.GETS(RCONTAINER => CXML, NTABID => NCURRENT_SECTION, SROWID => 'NAME'); - /* Clob с показателями раздела */ - CSECTION_CLOB := PKG_CONTVALLOC2NS.GETLC(RCONTAINER => CXML, NTABID => NCURRENT_SECTION, SROWID => 'CLOB'); - /* Формирование элемента XML с данными о разделе */ - PKG_XFAST.DOWN_NODE(SNAME => 'SECTIONS'); - PKG_XFAST.ATTR(SNAME => 'NRN', NVALUE => NSECTION_RN); - PKG_XFAST.ATTR(SNAME => 'SCODE', SVALUE => SSECTION_CODE); - PKG_XFAST.ATTR(SNAME => 'SNAME', SVALUE => SSECTION_NAME); - PKG_XFAST.ATTR(SNAME => 'NDELETE_ALLOW', - NVALUE => UTL_UNIT_ACTION_GET_ALLOW(SUNIT => SUNIT_RRPCONFSCTN, - SACTION => SACTION_DELETE, - NRN => NSECTION_RN)); - PKG_XFAST.VALUE_XML(LCVALUE => CSECTION_CLOB); - /* Добавляем информацию о составах показателей */ - PKG_XFAST.DOWN_NODE(SNAME => 'MARK_CNS'); - /* Цикл по составам показателей раздела */ - for REC in (select T.PRN, - T.RN, - T.NUMB - from RRPCONFSCTNMRK M, - RRPCONFSCTNMRKCN T - where M.PRN = NSECTION_RN - and T.PRN = M.RN - order by M.RN, - T.NUMB asc) + /* Инициализируем колонки таблицы данных */ + COLUMNS_INIT(RDG => RDG, NRRPCONFSCTN => S.NRN, NCOL_ORDER => NCOL_ORDER, NCOL_WIDTH => NMRKS_DG_COL_WIDTH); + /* Открываем запрос по составу уникальных строк раздела */ + OPEN_ROWS_COLS_CUR(NRRPCONFSCTN => NRRPCONFSCTN, STABLE => 'RRPROW', NORDER => NROW_ORDER, ICURSOR => ICURSOR); + /* Обходим выбранные записи строк */ + while (PKG_SQL_DML.FETCH_ROWS(ICURSOR => ICURSOR) > 0) loop - /* Добавляем состав */ - PKG_XFAST.DOWN_NODE(SNAME => 'MARK_CN'); - PKG_XFAST.ATTR(SNAME => 'NPRN', NVALUE => REC.PRN); - PKG_XFAST.ATTR(SNAME => 'NRN', NVALUE => REC.RN); - PKG_XFAST.ATTR(SNAME => 'SNUMB', SVALUE => REC.NUMB); - PKG_XFAST.ATTR(SNAME => 'SDESC', - SVALUE => UTL_RRPCONFSCTNMRKCN_GET_DESC(NCOMPANY => NCOMPANY, NRRPCONFSCTNMRKCN => REC.RN)); - PKG_XFAST.UP(); + /* Считываем рег. номер строки */ + PKG_SQL_DML.COLUMN_VALUE_NUM(ICURSOR => ICURSOR, IPOSITION => 1, NVALUE => NROW_RN); + /* Считываем наименование строки */ + PKG_SQL_DML.COLUMN_VALUE_STR(ICURSOR => ICURSOR, IPOSITION => 2, SVALUE => SROW_NAME); + /* Заполняем наименование строки */ + PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SROW_NAME', SVALUE => SROW_NAME, BCLEAR => true); + /* Обходим сформированные колонки таблицы данных */ + for I in RDG.RCOL_DEFS.FIRST .. RDG.RCOL_DEFS.LAST + loop + /* Первую пропускаем - она зарезервирована под наименование строки */ + if (I > RDG.RCOL_DEFS.FIRST) then + /* Определим рег. номер графы по её наименованию */ + NCOL_RN := RRPCOLUMN_BY_DG_COL_NAME(SDG_COL_NAME => RDG.RCOL_DEFS(I).SNAME); + /* Заполняем графу описанием показателя */ + PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, + SNAME => RDG.RCOL_DEFS(I).SNAME, + SVALUE => RRPCONFSCTNMRK_GET_DESC(NCOMPANY => NCOMPANY, + NRRPCONFSCTN => S.NRN, + NRRPROW => NROW_RN, + NRRPCOLUMN => NCOL_RN)); + end if; + end loop; + /* Добавим строку для раздела */ + PKG_P8PANELS_VISUAL.TDG_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW); end loop; - PKG_XFAST.UP(); - PKG_XFAST.UP(); + /* Освобождаем курсор */ + PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR); + /* Сериализуем описание */ + COUT := PKG_P8PANELS_VISUAL.TDG_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => 1); end loop; - PKG_XFAST.UP(); - /* Сериализуем описание */ - COUT := PKG_XFAST.SERIALIZE_TO_CLOB(); - PKG_XFAST.EPILOGUE(); - /* Очистка контейнера */ - PKG_CONTVALLOC2NS.PURGE(RCONTAINER => CXML); - end RRPCONF_GET_SECTIONS; + exception + when others then + if (PKG_SQL_DML.IS_OPEN(ICURSOR => ICURSOR)) then + PKG_SQL_DML.CLOSE_CURSOR(ICURSOR => ICURSOR); + end if; + raise; + end RRPCONFSCTN_GET; /* Добавление раздела регламентированного отчёта */ procedure RRPCONFSCTN_INSERT @@ -1279,234 +1423,74 @@ create or replace package body PKG_P8PANELS_RRPCONFED as /* Удаление раздела регламентированного отчёта */ procedure RRPCONFSCTN_DELETE ( - NRN in number -- Рег. номер раздела + NRN in number -- Рег. номер раздела ) is - NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Рег. номер организации begin - /* Если действие недоступно для удаления */ - if (UTL_UNIT_ACTION_GET_ALLOW(SUNIT => SUNIT_RRPCONFSCTN, SACTION => SACTION_DELETE, NRN => NRN) = 0) then - P_EXCEPTION(0, - 'Данный раздел используется в сформированных документах/параметрах документа/дочерний раздел. Удаление запрещено.'); - end if; /* Удалим раздел */ - P_RRPCONFSCTN_DELETE(NRN => NRN, NCOMPANY => NCOMPANY); + P_RRPCONFSCTN_DELETE(NCOMPANY => GET_SESSION_COMPANY(), NRN => NRN); end RRPCONFSCTN_DELETE; - - /* Получение кодов настройки, раздела и показателя раздела по ид. показателя раздела */ - procedure RRPCONFSCTNMRK_GET_CODES + + /* Получение описания настройки регламентированного отчета */ + procedure RRPCONF_GET ( - NRN in number, -- Рег. номер показателя раздела - SRRPCONF out varchar2, -- Мнемокод настройки формы регламентированного отчёта - SRRPCONFSCTN out varchar2, -- Мнемокод раздела - SRRPCONFSCTNMRK out varchar2 -- Мнемокод показателя раздела + NRRPCONF in number, -- Рег. номер настройки форм регламентированного отчёта + COUT out clob -- Описание настройки ) is + NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Организация сеанса + SNAME_SHORT PKG_STD.TSTRING; -- Краткое наименование раздела begin - /* Считываем данные показателя/раздела/настройки */ - begin - select C.CODE, - S.CODE, - M.CODE - into SRRPCONF, - SRRPCONFSCTN, - SRRPCONFSCTNMRK - from RRPCONF C, - RRPCONFSCTN S, - RRPCONFSCTNMRK M - where M.RN = NRN - and S.RN = M.PRN - and C.RN = S.PRN; - exception - when others then - P_EXCEPTION(0, - 'Не определен показатель настройки регламентированного отчета.'); - end; - end RRPCONFSCTNMRK_GET_CODES; - - /* Формирование кода и наименования показателя раздела регламентированного отчёта */ - procedure RRPCONFSCTNMRK_GET_CODE_NAME - ( - NRRPCONFSCTN in number, -- Рег. номер раздела - NRRPROW in number, -- Рег. номер строки - NRRPCOLUMN in number, -- Рег. номер графы - SCODE out varchar2, -- Мнемокод показателя раздела - SNAME out varchar2 -- Наименование показателя раздела - ) - is - NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Рег. номер организации - RRRPCONFSCTN RRPCONFSCTN%rowtype; -- Запись раздела регламентированного отчета - RRRPROW RRPROW%rowtype; -- Запись строки регламентированного отчета - RRRPCOLUMN RRPCOLUMN%rowtype; -- Запись графы регламентированного отчета - begin - /* Считываем запись раздела регламентированного отчета */ - RRRPCONFSCTN := GET_RRPCONFSCTN_ID(NFLAG_SMART => 1, NCOMPANY => NCOMPANY, NRN => NRRPCONFSCTN); - /* Считываем запись строки регламентированного отчета */ - RRRPROW := GET_RRPROW_ID(NFLAG_SMART => 1, NCOMPANY => NCOMPANY, NRN => NRRPROW); - /* Считываем запись графы регламентированного отчета */ - RRRPCOLUMN := GET_RRPCOLUMN_ID(NFLAG_SMART => 1, NCOMPANY => NCOMPANY, NRN => NRRPCOLUMN); - /* Если все записи считаны */ - if ((RRRPCONFSCTN.RN is not null) and (RRRPROW.RN is not null) and (RRRPCOLUMN.RN is not null)) then - /* Сформируем код показателя */ - P_RRPCONFSCTNMRK_MAKE_CODE(SRRPCONFSCTN => RRRPCONFSCTN.CODE, - SRRPROW => RRRPROW.CODE, - SRRPCOLUMN => RRRPCOLUMN.CODE, - SCODE => SCODE); - /* Сформируем наименование показателя */ - P_RRPCONFSCTNMRK_MAKE_NAME(NCOMPANY => NCOMPANY, - NRRPROW => RRRPROW.RN, - NRRPCOLUMN => RRRPCOLUMN.RN, - NCHANGE_NAME => 1, - NCHANGE_NAME_PARENT => 0, - SNAME => SNAME); - end if; - end RRPCONFSCTNMRK_GET_CODE_NAME; - - /* Формирование кода и наименования показателя раздела регламентированного отчёта */ - procedure RRPCONFSCTNMRK_GET_NAME - ( - NRRPCONFSCTNMRK in number, -- Рег. номер показателя - SNAME out varchar2 -- Наименование показателя раздела - ) - is - NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Рег. номер организации - RRRPCONFSCTNMRK RRPCONFSCTNMRK%rowtype; -- Запись показателя регламентированного отчета - begin - /* Считываем запись раздела регламентированного отчета */ - RRRPCONFSCTNMRK := GET_RRPCONFSCTNMRK_ID(NFLAG_SMART => 1, NCOMPANY => NCOMPANY, NRN => NRRPCONFSCTNMRK); - /* Указываем наименование показателя */ - SNAME := RRRPCONFSCTNMRK.NAME; - end RRPCONFSCTNMRK_GET_NAME; - - /* Добавление показателя раздела регламентированного отчёта */ - procedure RRPCONFSCTNMRK_INSERT - ( - NPRN in number, -- Рег. номер раздела - SCODE in varchar2, -- Мнемокод показателя раздела - SNAME in varchar2, -- Наименование показателя раздела - NRRPROW in number, -- Рег. номер строки - NRRPCOLUMN in number, -- Рег. номер графы - NRN out number -- Рег. номер созданной записи - ) - is - NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Рег. номер организации - RRRPROW RRPROW%rowtype; -- Запись строки регламентированного отчета - RRRPVERSION_ROW RRPVERSION%rowtype; -- Запись редакции строки регламентированного отчета - RRRPCOLUMN RRPCOLUMN%rowtype; -- Запись графы регламентированного отчета - RRRPVERSION_COL RRPVERSION%rowtype; -- Запись редакции графы регламентированного отчета - begin - /* Если строка не указана */ - if (NRRPROW is null) then - P_EXCEPTION(0, - 'Ошибка считывания строки регламентированного отчета.'); - end if; - /* Если графа не указана */ - if (NRRPCOLUMN is null) then - P_EXCEPTION(0, - 'Ошибка считывания графы регламентированного отчета.'); - end if; - /* Считываем запись строки регламентированного отчета */ - RRRPROW := GET_RRPROW_ID(NFLAG_SMART => 0, NCOMPANY => NCOMPANY, NRN => NRRPROW); - /* Считываем запись графы регламентированного отчета */ - RRRPCOLUMN := GET_RRPCOLUMN_ID(NFLAG_SMART => 0, NCOMPANY => NCOMPANY, NRN => NRRPCOLUMN); - /* Считываем запись редакции строки регламентированного отчета */ - RRRPVERSION_ROW := GET_RRPVERSION_ID(NFLAG_SMART => 0, NCOMPANY => NCOMPANY, NRN => RRRPROW.RRPVERSION); - /* Считываем запись редакции графы регламентированного отчета */ - RRRPVERSION_COL := GET_RRPVERSION_ID(NFLAG_SMART => 0, NCOMPANY => NCOMPANY, NRN => RRRPCOLUMN.RRPVERSION); - /* Добавим показатель */ - P_RRPCONFSCTNMRK_INSERT(NCOMPANY => NCOMPANY, - NPRN => NPRN, - NNUMB => F_RRPCONFSCTNMRK_NEXT_NUMB(NCOMPANY => NCOMPANY, NPRN => NPRN), - SCODE => SCODE, - SNAME => SNAME, - SRRPROW => RRRPROW.CODE, - SRRPVERSION_ROW => RRRPVERSION_ROW.CODE, - SRRPCOLUMN => RRRPCOLUMN.CODE, - SRRPVERSION_COLUMN => RRRPVERSION_COL.CODE, - SPKG_ROW => null, - SPRC_ROW => null, - SPKG_COL => null, - SPRC_COL => null, - SRRPPRM => null, - NIGNORE_ZOOM => 0, - NIGNORE_SHARP => 0, - SCLSF_CODE => null, - SNOTE => null, - NDUP_RN => null, - NRN => NRN); - end RRPCONFSCTNMRK_INSERT; - - /* Исправление показателя раздела регламентированного отчёта */ - procedure RRPCONFSCTNMRK_UPDATE - ( - NRN in number, -- Рег. номер показателя раздела - SNAME in varchar2 -- Новое наименование - ) - is - NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Рег. номер организации - RESSCTNMRK RRPCONFSCTNMRK%rowtype; -- Запись настройки показателя регламентированного отчета - RESROW RRPROW%rowtype; -- Запись строки регламентированного отчета - RESCOLUMN RRPCOLUMN%rowtype; -- Запись графы регламентированного отчета - RRRPPRM RRPPRM%rowtype; -- Запись типового параметра регламентированного отчета - SROWVER PKG_STD.TSTRING; -- Мнемокод редакции строки - SCOLVER PKG_STD.TSTRING; -- Мнемокод редакции графы - begin - /* Получение записи параметра раздела */ - RESSCTNMRK := GET_RRPCONFSCTNMRK_ID(NFLAG_SMART => 0, NCOMPANY => NCOMPANY, NRN => NRN); - /* Получение записи строки */ - RESROW := GET_RRPROW_ID(NFLAG_SMART => 0, NCOMPANY => NCOMPANY, NRN => RESSCTNMRK.RRPROW); - /* Получение записи графы */ - RESCOLUMN := GET_RRPCOLUMN_ID(NFLAG_SMART => 0, NCOMPANY => NCOMPANY, NRN => RESSCTNMRK.RRPCOLUMN); - /* Получение мнемокода редакции строки */ - if (RESROW.RRPVERSION is not null) then - SROWVER := GET_RRPVERSION_CODE_ID(NFLAG_SMART => 0, NRN => RESROW.RRPVERSION); - end if; - /* Получение мнемокода редакции графы */ - if (RESCOLUMN.RRPVERSION is not null) then - SCOLVER := GET_RRPVERSION_CODE_ID(NFLAG_SMART => 0, NRN => RESCOLUMN.RRPVERSION); - end if; - /* Получение записи типового параметра */ - if (RESSCTNMRK.RRPPRM is not null) then - RRRPPRM := GET_RRPPRM_ID(NFLAG_SMART => 0, NCOMPANY => NCOMPANY, NRN => RESSCTNMRK.RRPPRM); - end if; - /* Исправим показатель */ - P_RRPCONFSCTNMRK_UPDATE(NRN => NRN, - NCOMPANY => NCOMPANY, - NNUMB => RESSCTNMRK.NUMB, - SCODE => RESSCTNMRK.CODE, - SNAME => SNAME, - SRRPROW => RESROW.CODE, - SRRPVERSION_ROW => SROWVER, - SRRPCOLUMN => RESCOLUMN.CODE, - SRRPVERSION_COLUMN => SCOLVER, - SPKG_ROW => RESSCTNMRK.PKG_ROW, - SPRC_ROW => RESSCTNMRK.PRC_ROW, - SPKG_COL => RESSCTNMRK.PKG_COL, - SPRC_COL => RESSCTNMRK.PRC_COL, - SRRPPRM => RRRPPRM.CODE, - NIGNORE_ZOOM => RESSCTNMRK.IGNORE_ZOOM, - NIGNORE_SHARP => RESSCTNMRK.IGNORE_SHARP, - SCLSF_CODE => RESSCTNMRK.CLSF_CODE, - NFORMULA_UPDATE => 0, - SNOTE => RESSCTNMRK.NOTE); - end RRPCONFSCTNMRK_UPDATE; - - /* Удаление показателя раздела регламентированного отчёта */ - procedure RRPCONFSCTNMRK_DELETE - ( - NRN in number -- Рег. номер показателя раздела - ) - is - NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Рег. номер организации - begin - /* Если действие недоступно для удаления */ - if (UTL_UNIT_ACTION_GET_ALLOW(SUNIT => SUNIT_RRPCONFSCTNMRK, SACTION => SACTION_DELETE, NRN => NRN) = 0) then - P_EXCEPTION(0, - 'Данный показатель используется в сформированных документах. Удаление запрещено.'); - end if; - /* Удалим показатель */ - P_RRPCONFSCTNMRK_DELETE(NCOMPANY => NCOMPANY, NRN => NRN); - end RRPCONFSCTNMRK_DELETE; + /* Формируем XML с данными */ + PKG_XFAST.PROLOGUE(ITYPE => PKG_XFAST.CONTENT_); + PKG_XFAST.DOWN_NODE(SNAME => 'XDATA'); + /* Обратимся к настройке */ + for CONF in (select C.RN NRN, + C.NAME SNAME + from RRPCONF C + where C.RN = NRRPCONF + and exists (select null from V_USERPRIV UP where UP.CATALOG = C.CRN)) + loop + /* Добавим в выдачу сведения о настройке */ + PKG_XFAST.DOWN_NODE(SNAME => 'XCONF'); + PKG_XFAST.ATTR(SNAME => 'SNAME', SVALUE => CONF.SNAME); + PKG_XFAST.UP(); + /* Обходим разделы настройки */ + for C in (select T.RN NRN, + T.CODE SCODE, + T.NAME SNAME + from RRPCONFSCTN T + where T.PRN = CONF.NRN + and exists (select null from V_USERPRIV UP where UP.CATALOG = T.CRN) + order by T.CODE, + T.NAME) + loop + /* Составим краткое наименование */ + SNAME_SHORT := SUBSTR(C.SNAME, 1, NSECTION_NAME_MAX_LEN); + if (LENGTH(C.SNAME) > NSECTION_NAME_MAX_LEN) then + SNAME_SHORT := SNAME_SHORT || '...'; + end if; + /* Формирование элемента XML с данными о разделе */ + PKG_XFAST.DOWN_NODE(SNAME => 'XSECTIONS'); + PKG_XFAST.ATTR(SNAME => 'NRN', NVALUE => C.NRN); + PKG_XFAST.ATTR(SNAME => 'SCODE', SVALUE => C.SCODE); + PKG_XFAST.ATTR(SNAME => 'SNAME', SVALUE => C.SNAME); + PKG_XFAST.ATTR(SNAME => 'SNAME_SHORT', SVALUE => SNAME_SHORT); + PKG_XFAST.ATTR(SNAME => 'NDELETE_ALLOW', + NVALUE => UTL_UNIT_ACTION_GET_ALLOW(NCOMPANY => NCOMPANY, + NRN => C.NRN, + SUNIT => SUNIT_RRPCONFSCTN, + SACTION => SACTION_DELETE)); + PKG_XFAST.UP(); + end loop; + end loop; + /* Закрываем описание */ + PKG_XFAST.UP(); + /* Сериализуем описание */ + COUT := PKG_XFAST.SERIALIZE_TO_CLOB(); + /* Завершаем формирование XML */ + PKG_XFAST.EPILOGUE(); + end RRPCONF_GET; end PKG_P8PANELS_RRPCONFED; /