From 4c1a0cd3395c69023b6a3d2988db80bf5bd67e98 Mon Sep 17 00:00:00 2001 From: tsygankoviva Date: Thu, 6 Aug 2026 16:23:30 +0300 Subject: [PATCH] =?UTF-8?q?vsp-choose-form2:=20=D0=B2=D1=8B=D0=B1=D0=BE?= =?UTF-8?q?=D1=80=20=D0=92=D0=A1=D0=9F=20=D0=BD=D0=B0=20=D1=84=D1=80=D0=BE?= =?UTF-8?q?=D0=BD=D1=82=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RealtimeTable/Cell/Cell/Cell.jsx | 342 +- .../Cell/EditCell/VspDropdownEditCell.jsx | 121 + .../RealtimeTable/RealtimeTable.jsx | 1119 +-- .../RealtimeTable/constants/FORM_2/AHR.js | 6380 ++++++++--------- .../RealtimeTable/constants/FORM_2/CAP.js | 37 +- .../RealtimeTable/constants/FORM_2/OPER.js | 37 +- .../RealtimeTable/contexts/RealtimeContext.js | 747 +- .../components/RealtimeTable/tableColumns.jsx | 339 +- 8 files changed, 4651 insertions(+), 4471 deletions(-) create mode 100644 web/src/components/RealtimeTable/Cell/EditCell/VspDropdownEditCell.jsx diff --git a/web/src/components/RealtimeTable/Cell/Cell/Cell.jsx b/web/src/components/RealtimeTable/Cell/Cell/Cell.jsx index 472c89c..ffb644f 100644 --- a/web/src/components/RealtimeTable/Cell/Cell/Cell.jsx +++ b/web/src/components/RealtimeTable/Cell/Cell/Cell.jsx @@ -1,214 +1,228 @@ -import React, { memo, useMemo, useCallback } from 'react'; +import React, { useMemo, useCallback } from 'react'; import { useRealtime } from '../../contexts/RealtimeContext'; // Константы вне компонента const BASE_CELL_STYLES = { - width: '100%', - height: '100%', - display: 'flex', - alignItems: 'center', - justifyContent: 'center', - boxSizing: 'border-box', - position: 'absolute', - top: 0, - left: 0, - right: 0, - bottom: 0, - border: '2px solid transparent', - padding: '8px', + width: '100%', + height: '100%', + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + boxSizing: 'border-box', + position: 'absolute', + top: 0, + left: 0, + right: 0, + bottom: 0, + border: '2px solid transparent', + padding: '8px', }; const LOCKED_STYLES = { - border: '2px solid #e0e0e0', - backgroundColor: '#f5f5f5', - cursor: 'not-allowed', - opacity: 0.85, + border: '2px solid #e0e0e0', + backgroundColor: '#f5f5f5', + cursor: 'not-allowed', + opacity: 0.85, }; const INVALID_STYLES = { - border: '2px solid #D32F2F', - backgroundColor: '#FDEDED', - color: '#C60C0C', + border: '2px solid #D32F2F', + backgroundColor: '#FDEDED', + color: '#C60C0C', }; const LOCK_BADGE_STYLES = { - position: 'absolute', - top: '2px', - right: '2px', - background: 'rgba(0, 0, 0, 0.7)', - color: 'white', - fontSize: '9px', - padding: '1px 4px', - borderRadius: '3px', - pointerEvents: 'none', - zIndex: 10, - fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif', - letterSpacing: '0.3px', - backdropFilter: 'blur(4px)', - border: '1px solid rgba(255, 255, 255, 0.1)', + position: 'absolute', + top: '2px', + right: '2px', + background: 'rgba(0, 0, 0, 0.7)', + color: 'white', + fontSize: '9px', + padding: '1px 4px', + borderRadius: '3px', + pointerEvents: 'none', + zIndex: 10, + fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif', + letterSpacing: '0.3px', + backdropFilter: 'blur(4px)', + border: '1px solid rgba(255, 255, 255, 0.1)', }; const CONTAINER_STYLES = { - display: '-webkit-box', - WebkitBoxOrient: 'vertical', - WebkitLineClamp: 3, - overflow: 'hidden', - whiteSpace: 'pre-wrap', - wordBreak: 'break-word', + display: '-webkit-box', + WebkitBoxOrient: 'vertical', + WebkitLineClamp: 3, + overflow: 'hidden', + whiteSpace: 'pre-wrap', + wordBreak: 'break-word', }; const INTEGER_COLUMN_IDS = new Set([ - 'data.header.num_group', - 'data.nomenclature_group_id', - 'data.header.item_id', - 'data.article_id', - 'data.code_razdela', + 'data.header.num_group', + 'data.nomenclature_group_id', + 'data.header.item_id', + 'data.article_id', + 'data.code_razdela', ]); const getColorBrightness = (hexColor) => { - if (!hexColor) return 255; - const color = hexColor.replace('#', ''); - let r, g, b; - if (color.length === 3) { - r = parseInt(color[0] + color[0], 16); - g = parseInt(color[1] + color[1], 16); - b = parseInt(color[2] + color[2], 16); - } else if (color.length === 6) { - r = parseInt(color.substring(0, 2), 16); - g = parseInt(color.substring(2, 4), 16); - b = parseInt(color.substring(4, 6), 16); - } else { - return 255; - } - return (0.299 * r + 0.587 * g + 0.114 * b); + if (!hexColor) return 255; + const color = hexColor.replace('#', ''); + let r; + let g; + let b; + if (color.length === 3) { + r = Number.parseInt(color[0] + color[0], 16); + g = Number.parseInt(color[1] + color[1], 16); + b = Number.parseInt(color[2] + color[2], 16); + } else if (color.length === 6) { + r = Number.parseInt(color.substring(0, 2), 16); + g = Number.parseInt(color.substring(2, 4), 16); + b = Number.parseInt(color.substring(4, 6), 16); + } else { + return 255; + } + return 0.299 * r + 0.587 * g + 0.114 * b; }; const formatNumber = (value, asInteger = false) => { - if (value === null || value === undefined || value === '') return String(value || ''); - const num = Number(value); - if (isNaN(num)) return String(value); - return num.toLocaleString('ru-RU', { - minimumFractionDigits: asInteger ? 0 : 1, - maximumFractionDigits: asInteger ? 0 : 1, - useGrouping: true, - }); + if (value === null || value === undefined || value === '') return String(value || ''); + const num = Number(value); + if (Number.isNaN(num)) return String(value); + return num.toLocaleString('ru-RU', { + minimumFractionDigits: asInteger ? 0 : 1, + maximumFractionDigits: asInteger ? 0 : 1, + useGrouping: true, + }); }; // Оптимизированная функция подсветки const createHighlightedContent = (originalValue, displayValue, searchQueries) => { - const cleanQueries = searchQueries.filter(Boolean); - if (cleanQueries.length === 0) return displayValue; + const cleanQueries = searchQueries.filter(Boolean); + if (cleanQueries.length === 0) return displayValue; - const searchStr = String(originalValue ?? displayValue); - const escapedQueries = cleanQueries.map(q => q.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')); - const regex = new RegExp(`(${escapedQueries.join('|')})`, 'gi'); + const searchStr = String(originalValue ?? displayValue); + const escapedQueries = cleanQueries.map((q) => q.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')); + const regex = new RegExp(`(${escapedQueries.join('|')})`, 'gi'); - if (!regex.test(searchStr)) return displayValue; + if (!regex.test(searchStr)) return displayValue; - const parts = searchStr.split(regex); - return parts.map((part, index) => { - if (!regex.test(part)) return part; - return React.createElement('mark', { - key: index, - style: { - backgroundColor: '#ffeb3b', - color: '#000', - fontWeight: 'bold', - padding: '0 2px', - borderRadius: '2px', - }, - }, part); - }); + const parts = searchStr.split(regex); + return parts.map((part, index) => { + if (!regex.test(part)) return part; + return React.createElement( + 'mark', + { + key: index, + style: { + backgroundColor: '#ffeb3b', + color: '#000', + fontWeight: 'bold', + padding: '0 2px', + borderRadius: '2px', + }, + }, + part, + ); + }); }; const CellComponent = ({ - cell, - row, - column, - onClick, - globalFilter, - columnFilter, - backgroundColor, - color, - isEditable, - isUpdating, - onCellNumberClick, - isInvalid, + cell, + row, + column, + onClick, + globalFilter, + columnFilter, + backgroundColor, + color, + isEditable, + isUpdating, + onCellNumberClick, + isInvalid, + vspOptions, }) => { - const { lockedCells } = useRealtime(); - const cellKey = `${row.id}_${column.id}`; - const isLocked = lockedCells.includes(cellKey); + const { lockedCells } = useRealtime(); + const cellKey = `${row.id}_${column.id}`; + const isLocked = lockedCells.includes(cellKey); - // Мемоизация значения - const { rawValue, displayValue, isNumeric } = useMemo(() => { - const value = cell.getValue(); - const isNum = !isNaN(Number(value)) && value !== null && value !== undefined && value !== ''; - let display = String(value || ''); + const isVspDropdown = column?.columnDef?.editType === 'vsp_dropdown'; - if (isNum) { - const asInteger = INTEGER_COLUMN_IDS.has(column.id); - display = formatNumber(value, asInteger); - } + const { rawValue, displayValue, isNumeric } = useMemo(() => { + const value = cell.getValue(); + const isNum = !Number.isNaN(Number(value)) && value !== null && value !== undefined && value !== ''; + let display = String(value || ''); - return { rawValue: value, displayValue: display, isNumeric: isNum }; - }, [cell, column.id]); + if (isVspDropdown && value != null) { + const vsp = vspOptions?.find((v) => v.id === Number(value)); + if (vsp) { + return { rawValue: value, displayValue: vsp.registration_number, isNumeric: false }; + } + } - const highlightedContent = useMemo(() => { - const searchQueries = [globalFilter, columnFilter]; - return createHighlightedContent(rawValue, displayValue, searchQueries); - }, [rawValue, displayValue, globalFilter, columnFilter]); + if (isNum) { + const asInteger = INTEGER_COLUMN_IDS.has(column.id); + display = formatNumber(value, asInteger); + } - const textColor = useMemo(() => { - if (isLocked) return '#999999'; - const brightness = getColorBrightness(backgroundColor); - return brightness < 128 ? '#ffffff' : '#000000'; - }, [backgroundColor, isLocked]); + return { rawValue: value, displayValue: display, isNumeric: isNum }; + }, [cell, column.id, isVspDropdown, vspOptions]); - const cellStyles = useMemo(() => ({ - ...BASE_CELL_STYLES, - backgroundColor: isLocked ? '#f5f5f5' : backgroundColor, - color: textColor, - ...(isLocked ? LOCKED_STYLES : {}), - ...(isInvalid ? INVALID_STYLES : {}), - }), [backgroundColor, isInvalid, isLocked, textColor]); + const highlightedContent = useMemo(() => { + const searchQueries = [globalFilter, columnFilter]; + return createHighlightedContent(rawValue, displayValue, searchQueries); + }, [rawValue, displayValue, globalFilter, columnFilter]); - const lockBadge = useMemo(() => { - if (!isLocked) return null; - return
🔒
; - }, [isLocked]); + const textColor = useMemo(() => { + if (isLocked) return '#999999'; + const brightness = getColorBrightness(backgroundColor); + return brightness < 128 ? '#ffffff' : '#000000'; + }, [backgroundColor, isLocked]); - const handleClick = useCallback(() => { - if (!isLocked && onClick) { - onClick(); - } - }, [isLocked, onClick]); + const cellStyles = useMemo( + () => ({ + ...BASE_CELL_STYLES, + backgroundColor: isLocked ? '#f5f5f5' : backgroundColor, + color: textColor, + ...(isLocked ? LOCKED_STYLES : {}), + ...(isInvalid ? INVALID_STYLES : {}), + }), + [backgroundColor, isInvalid, isLocked, textColor], + ); - return ( -
- {highlightedContent} - {lockBadge} -
- ); + const lockBadge = useMemo(() => { + if (!isLocked) return null; + return
🔒
; + }, [isLocked]); + + const handleClick = useCallback(() => { + if (!isLocked && onClick) { + onClick(); + } + }, [isLocked, onClick]); + + return ( +
+ {highlightedContent} + {lockBadge} +
+ ); }; const Cell = React.memo(CellComponent, (prevProps, nextProps) => { - // Возвращаем true если пропсы равны (не нужно перерендеривать) - return ( - prevProps.cell.getValue() === nextProps.cell.getValue() && - prevProps.row.id === nextProps.row.id && - prevProps.column.id === nextProps.column.id && - prevProps.globalFilter === nextProps.globalFilter && - prevProps.columnFilter === nextProps.columnFilter && - prevProps.backgroundColor === nextProps.backgroundColor && - prevProps.isInvalid === nextProps.isInvalid && - prevProps.isEditable === nextProps.isEditable && - prevProps.isUpdating === nextProps.isUpdating && - prevProps.onCellNumberClick === nextProps.onCellNumberClick - ); + return ( + prevProps.cell.getValue() === nextProps.cell.getValue() && + prevProps.row.id === nextProps.row.id && + prevProps.column.id === nextProps.column.id && + prevProps.globalFilter === nextProps.globalFilter && + prevProps.columnFilter === nextProps.columnFilter && + prevProps.backgroundColor === nextProps.backgroundColor && + prevProps.isInvalid === nextProps.isInvalid && + prevProps.isEditable === nextProps.isEditable && + prevProps.isUpdating === nextProps.isUpdating && + prevProps.onCellNumberClick === nextProps.onCellNumberClick && + prevProps.vspOptions === nextProps.vspOptions + ); }); -export default Cell; \ No newline at end of file +export default Cell; diff --git a/web/src/components/RealtimeTable/Cell/EditCell/VspDropdownEditCell.jsx b/web/src/components/RealtimeTable/Cell/EditCell/VspDropdownEditCell.jsx new file mode 100644 index 0000000..172c31d --- /dev/null +++ b/web/src/components/RealtimeTable/Cell/EditCell/VspDropdownEditCell.jsx @@ -0,0 +1,121 @@ +import { FormControl, MenuItem, Select } from '@mui/material'; +import { memo, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'; +import { useRealtime } from '../../contexts/RealtimeContext'; + +const EDITOR_STYLES = { + position: 'absolute', + zIndex: 12, + top: 0, +}; + +const VspDropdownEditCell = memo(({ refCell, onChange, disabled, value, table }) => { + const { endEditing: contextEndEditing, vspOptions } = useRealtime(); + + const [selectedValue, setSelectedValue] = useState(() => value ?? ''); + const [position, setPosition] = useState(); + const [open, setOpen] = useState(false); + + const refFinished = useRef(false); + + useEffect(() => { + const timer = setTimeout(() => { + setOpen(true); + }, 80); + return () => clearTimeout(timer); + }, []); + + useLayoutEffect(() => { + if (!refCell?.current) return; + + const td = refCell.current.offsetParent; + const tr = td?.offsetParent; + + if (td && tr) { + setPosition({ + left: td.offsetLeft, + width: td.offsetWidth, + translateY: tr.style.transform || '', + }); + } + }, [refCell]); + + const finishEditing = useCallback(() => { + if (refFinished.current) return; + refFinished.current = true; + table.setEditingCell(null); + const editingCell = table.getState().editingCell; + if (editingCell) { + contextEndEditing?.(editingCell.row, editingCell.column); + } + }, [table, contextEndEditing]); + + const handleSelectChange = useCallback( + (e) => { + const val = e.target.value; + if (val == null || val === '') return; + refFinished.current = true; + setSelectedValue(val); + onChange?.(val); + const editingCell = table.getState().editingCell; + if (editingCell) { + contextEndEditing?.(editingCell.row, editingCell.column); + } + }, + [onChange, table, contextEndEditing], + ); + + const handleSelectClose = useCallback( + (_event, reason) => { + if (reason === 'selectOption') return; + finishEditing(); + }, + [finishEditing], + ); + + const editorStyles = useMemo( + () => ({ + ...EDITOR_STYLES, + left: position?.left || 0, + width: position?.width || 0, + transform: position?.translateY || 0, + }), + [position], + ); + + return ( + + + {position && ( +
+ + + +
+ )} + + + ); +}); + +VspDropdownEditCell.displayName = 'VspDropdownEditCell'; + +export default VspDropdownEditCell; diff --git a/web/src/components/RealtimeTable/RealtimeTable.jsx b/web/src/components/RealtimeTable/RealtimeTable.jsx index 2711f3f..30d66f7 100644 --- a/web/src/components/RealtimeTable/RealtimeTable.jsx +++ b/web/src/components/RealtimeTable/RealtimeTable.jsx @@ -1,627 +1,642 @@ +import { MaterialReactTable, useMaterialReactTable } from 'material-react-table'; import React, { useState, useMemo, useRef, useEffect, useCallback, useTransition } from 'react'; import { createPortal } from 'react-dom'; -import { - useMaterialReactTable, - MaterialReactTable, -} from 'material-react-table'; -import useRealtimeData from './hooks/useRealtimeData'; -import { getTableColumns } from './tableColumns'; -import { Cell, EditCell } from './index'; -import { TableHead } from './TableHead/TableHead'; -import SettingsPanel from './SettingPanel/SettingPanel'; import { ColumnSelectionOverlay } from './ColumnSelectionOverlay/ColumnSelectionOverlay'; +import SettingsPanel from './SettingPanel/SettingPanel'; +import { TableHead } from './TableHead/TableHead'; +import useRealtimeData from './hooks/useRealtimeData'; +import { Cell, EditCell } from './index'; +import { getTableColumns } from './tableColumns'; -import { useColumnSettings } from './hooks/useColumnSettings'; -import { useTableScale } from './hooks/useTableScale'; -import { useHeaderPortal } from './hooks/useHeaderPortal'; -import { useValidationRules } from './hooks/useValidationRules'; -import { - BASE_TABLE_CONFIG, - getTableBodyCellProps, - getTablePaperStyles, - TABLE_ROW_HEIGHT, -} from './constants/tableConfig'; -import { useRealtime } from './contexts/RealtimeContext'; -import { toast } from 'react-toastify'; import { CircularProgress } from '@mui/material'; -import { additionExpenseRowTable, additionVspRowTable } from './constants/addingRowConfig'; -import { SelectVspModal } from './Modals/SelectVspModal'; -import { SelectExpenseItemModal } from './Modals/SelectExpenseItemModal'; -import { getRowId } from './utils/rowUtils'; -import { FORM_TYPE_OPTIONS } from '../../constants/constants'; import { debounce } from '@mui/material'; +import { toast } from 'react-toastify'; +import { DictVspApi } from '../../api/dict-vsp'; import { CreateProgramModal } from './Modals/CreateProgramProjectModal'; +import { SelectExpenseItemModal } from './Modals/SelectExpenseItemModal'; +import { SelectVspModal } from './Modals/SelectVspModal'; +import { additionExpenseRowTable, additionVspRowTable } from './constants/addingRowConfig'; +import { BASE_TABLE_CONFIG, TABLE_ROW_HEIGHT, getTableBodyCellProps, getTablePaperStyles } from './constants/tableConfig'; +import { useRealtime } from './contexts/RealtimeContext'; +import { useColumnSettings } from './hooks/useColumnSettings'; +import { useHeaderPortal } from './hooks/useHeaderPortal'; +import { useTableScale } from './hooks/useTableScale'; +import { useValidationRules } from './hooks/useValidationRules'; +import { getRowId } from './utils/rowUtils'; const RealtimeTable = ({ formType, formId, sheetName, direction, year }) => { - const { data, setData, isLoading: isTableLoading, editingCells: dataEditingCells } = useRealtimeData(formId, sheetName, direction, formType, year); - const [globalFilter, setGlobalFilter] = useState(''); - const [showColumnFilters, setShowColumnFilters] = useState(false); - const [selectedColumnId, setSelectedColumnId] = useState(); - const [rowSelection, setRowSelection] = useState({}); - const [isLoadingData, setIsLoadingData] = useState(false); - const [isPending, startTransition] = useTransition(); - const [editingCell, setEditingCell] = useState(null); - const [columnsConfig, setColumnsConfig] = useState(null); - const { errors: validationErrors, isCellInvalid } = useValidationRules( - data, - columnsConfig?.columns, - ); + const { + data, + setData, + isLoading: isTableLoading, + editingCells: dataEditingCells, + } = useRealtimeData(formId, sheetName, direction, formType, year); + const [globalFilter, setGlobalFilter] = useState(''); + const [showColumnFilters, setShowColumnFilters] = useState(false); + const [selectedColumnId, setSelectedColumnId] = useState(); + const [rowSelection, setRowSelection] = useState({}); + const [isLoadingData, setIsLoadingData] = useState(false); + const [_isPending, startTransition] = useTransition(); + const [editingCell, setEditingCell] = useState(null); + const [columnsConfig, setColumnsConfig] = useState(null); + const { errors: validationErrors, isCellInvalid } = useValidationRules(data, columnsConfig?.columns); - const [isOpenModalSelectVsp, setIsOpenModalSelectVsp] = useState(false); - const [isOpenModalSelectExpenseItem, setIsOpenModalSelectExpenseItem] = useState(false); - const [isOpenModalCreateProgram, setIsOpenModalCreateProgram] = useState(false); - const [isOpenModalCreateProject, setIsOpenModalCreateProject] = useState(false); - const [isProgramCreate, setIsProgramCreate] = useState(false) + const [isOpenModalSelectVsp, setIsOpenModalSelectVsp] = useState(false); + const [isOpenModalSelectExpenseItem, setIsOpenModalSelectExpenseItem] = useState(false); + const [isOpenModalCreateProgram, setIsOpenModalCreateProgram] = useState(false); + const [_isOpenModalCreateProject, _setIsOpenModalCreateProject] = useState(false); + const [isProgramCreate, setIsProgramCreate] = useState(false); - const isVspAdditionRow = useMemo(() => { - if (!formType || !sheetName) return false; - if (!additionVspRowTable[formType]) return false; - return additionVspRowTable[formType].includes(sheetName); - }, [formType, sheetName]); + const isVspAdditionRow = useMemo(() => { + if (!formType || !sheetName) return false; + if (!additionVspRowTable[formType]) return false; + return additionVspRowTable[formType].includes(sheetName); + }, [formType, sheetName]); - const isAdditionExpenseItem = useMemo(() => { - if (!formType || !sheetName) return false; - if (!additionExpenseRowTable[formType]) return false; - return additionExpenseRowTable[formType].includes(sheetName); - }, [formType, sheetName]); + const isAdditionExpenseItem = useMemo(() => { + if (!formType || !sheetName) return false; + if (!additionExpenseRowTable[formType]) return false; + return additionExpenseRowTable[formType].includes(sheetName); + }, [formType, sheetName]); - const handleGlobalFilterChange = useCallback( - debounce((value) => { - startTransition(() => { - setGlobalFilter(value); - }); - }, 300), - [] - ); + const handleGlobalFilterChange = useCallback( + debounce((value) => { + startTransition(() => { + setGlobalFilter(value); + }); + }, 300), + [], + ); - const { - isConnected, - isAuthenticated, - subscribeToErrors, - subscribeToAuthSuccess, - error: wsError, - updateCell: contextUpdateCell, - addRow: contextAddRow, - deleteRow: contextDeleteRow, - startEditing: contextStartEditing, - addProgram: contextAddProgram, - addProject: contextAddProject, - } = useRealtime(); + const { + isConnected, + isAuthenticated, + subscribeToErrors, + subscribeToAuthSuccess, + error: wsError, + updateCell: contextUpdateCell, + addRow: contextAddRow, + deleteRow: contextDeleteRow, + startEditing: contextStartEditing, + addProgram: contextAddProgram, + addProject: contextAddProject, + setVspOptions, + } = useRealtime(); - const { - columnSizing, - columnPinning, - columnVisibility, - setColumnSizing, - setColumnPinning, - handlePinColumn, - handleUnpinColumn, - handleSetColumnWidth, - handleToggleColumnVisibility, - } = useColumnSettings(`${formId}_${formType}_${sheetName}_${direction}`); + const { + columnSizing, + columnPinning, + columnVisibility, + setColumnSizing, + setColumnPinning, + handlePinColumn, + handleUnpinColumn, + handleSetColumnWidth, + handleToggleColumnVisibility, + } = useColumnSettings(`${formId}_${formType}_${sheetName}_${direction}`); - const { headerPortalRef, containerRef } = useHeaderPortal(); - const rowVirtualizerRef = useRef(null); + const { headerPortalRef, containerRef } = useHeaderPortal(); + const rowVirtualizerRef = useRef(null); - const { sizeMult, setSizeMult, tableScaleStyle, tableWrapperStyle } = - useTableScale(); + const { sizeMult, setSizeMult, tableScaleStyle, tableWrapperStyle } = useTableScale(); - useEffect(() => { - rowVirtualizerRef.current?.measure?.(); - }, [sizeMult]); + useEffect(() => { + rowVirtualizerRef.current?.measure?.(); + }, [sizeMult]); - const configCache = useRef(new Map()); + const configCache = useRef(new Map()); - useEffect(() => { - if (!formType || !sheetName) return; - const cacheKey = `${formType}_${sheetName}`; + useEffect(() => { + if (!formType || !sheetName) return; + const cacheKey = `${formType}_${sheetName}`; - if (configCache.current.has(cacheKey)) { - setColumnsConfig(configCache.current.get(cacheKey)); - return; - } + if (configCache.current.has(cacheKey)) { + setColumnsConfig(configCache.current.get(cacheKey)); + return; + } - const loadConfig = async () => { - try { - const { config } = await import(`./constants/${formType}/${sheetName}.js`); - configCache.current.set(cacheKey, config.config); - setColumnsConfig(config.config); - } catch (error) { - console.error(`Failed to load config for ${formType}/${sheetName}:`, error); - setColumnsConfig({ columns: [], colors: {} }); - } - }; + const loadConfig = async () => { + try { + const { config } = await import(`./constants/${formType}/${sheetName}.js`); + configCache.current.set(cacheKey, config.config); + setColumnsConfig(config.config); + } catch (_error) { + setColumnsConfig({ columns: [], colors: {} }); + } + }; - loadConfig(); - }, [formType, sheetName]); + loadConfig(); + }, [formType, sheetName]); - const handleUpdateCell = useCallback(async (row, column, value) => { - return await contextUpdateCell(row, column, value); - }, [contextUpdateCell]); + useEffect(() => { + if (!formId || !columnsConfig?.columns) return; - const handleClickRowCell = useCallback((rowId) => { - setRowSelection((prev) => ({ - [rowId]: !prev[rowId], - })); - }, []) + const hasVspDropdown = (cols) => { + for (const col of cols) { + if (col.editType === 'vsp_dropdown') return true; + if (col.columns && hasVspDropdown(col.columns)) return true; + } + return false; + }; - const handleColumnSelect = useCallback((columnId) => { - setSelectedColumnId((prev) => { - const next = prev === columnId ? undefined : columnId; - return next; - }); - }, []); + if (!hasVspDropdown(columnsConfig.columns)) return; - useEffect(() => { - if (!selectedColumnId) return; + DictVspApi.getDropdownVsp({ form_id: formId }).then((data) => { + if (data.success) { + setVspOptions(data.result); + } + }); + }, [formId, columnsConfig, setVspOptions]); - const handleDocumentClick = (e) => { - if (e.target.closest('[data-col-select-id]')) return; - if (e.target.closest('[data-pin-panel]')) return; - if (e.target.closest('[data-validation-errors-menu]')) return; + const handleUpdateCell = useCallback( + async (row, column, value) => { + return await contextUpdateCell(row, column, value); + }, + [contextUpdateCell], + ); - setSelectedColumnId(undefined); - }; + const handleClickRowCell = useCallback((rowId) => { + setRowSelection((prev) => ({ + [rowId]: !prev[rowId], + })); + }, []); - document.addEventListener('mousedown', handleDocumentClick); - return () => document.removeEventListener('mousedown', handleDocumentClick); - }, [selectedColumnId]); + const handleColumnSelect = useCallback((columnId) => { + setSelectedColumnId((prev) => { + const next = prev === columnId ? undefined : columnId; + return next; + }); + }, []); - const handleCellUpdateError = useCallback((rowId, columnId, error) => { - console.error(`Error updating cell ${rowId}_${columnId}:`, error); - toast.error('Ошибка обновления ячейки'); - }, []); + useEffect(() => { + if (!selectedColumnId) return; - const columns = useMemo(() => { - if (!columnsConfig || !columnsConfig.columns) return []; - try { - return getTableColumns({ - Cell, - EditCell, - columnsConfig, - onCellUpdate: handleUpdateCell, - onCellNumberClick: handleClickRowCell, - onCellUpdateError: handleCellUpdateError, - isCellInvalid, - }); - } catch (error) { - console.error('Error creating columns:', error); - return []; - } - }, [ - columnsConfig, - handleCellUpdateError, - handleClickRowCell, - handleUpdateCell, - isCellInvalid, - ]); + const handleDocumentClick = (e) => { + if (e.target.closest('[data-col-select-id]')) return; + if (e.target.closest('[data-pin-panel]')) return; + if (e.target.closest('[data-validation-errors-menu]')) return; - const selectedColumnIdRef = useRef(selectedColumnId); + setSelectedColumnId(undefined); + }; - useEffect(() => { - selectedColumnIdRef.current = selectedColumnId; - }, [selectedColumnId]); + document.addEventListener('mousedown', handleDocumentClick); + return () => document.removeEventListener('mousedown', handleDocumentClick); + }, [selectedColumnId]); - const tableMeta = useMemo(() => ({ - updateCell: handleUpdateCell, - getSelectedColumnId: () => selectedColumnIdRef.current, - }), [handleUpdateCell]); + const handleCellUpdateError = useCallback((_rowId, _columnId, _error) => { + toast.error('Ошибка обновления ячейки'); + }, []); - const ROW_VIRTUALIZER_OPTIONS = { - overscan: 5, - scrollPaddingStart: 0, - scrollPaddingEnd: 0, - estimateSize: () => TABLE_ROW_HEIGHT, - measureElement: (el) => el?.offsetHeight || TABLE_ROW_HEIGHT, - }; + const columns = useMemo(() => { + if (!columnsConfig || !columnsConfig.columns) return []; + try { + return getTableColumns({ + Cell, + EditCell, + columnsConfig, + onCellUpdate: handleUpdateCell, + onCellNumberClick: handleClickRowCell, + onCellUpdateError: handleCellUpdateError, + isCellInvalid, + }); + } catch (_error) { + return []; + } + }, [columnsConfig, handleCellUpdateError, handleClickRowCell, handleUpdateCell, isCellInvalid]); - const createTableConfig = ({ - columns, - data, - columnSizing, - columnPinning, - columnVisibility, - globalFilter, - showColumnFilters, - rowSelection, - containerRef, - tableMeta, - setColumnSizing, - setColumnPinning, - editingCell, - contextStartEditing, - }) => ({ - ...BASE_TABLE_CONFIG, - columns, - data, - enableRowVirtualization: true, - enableColumnVirtualization: true, - rowVirtualizerInstanceRef: rowVirtualizerRef, - rowVirtualizerOptions: ROW_VIRTUALIZER_OPTIONS, - onEditingCellChange: (cell) => { - if (cell && !editingCell) { - contextStartEditing?.(cell.row, cell.column); - } - }, - columnVirtualizerOptions: ({ table }) => ({ - overscan: 10, - measureElement: (el) => { - if (!el) return 150; - const index = Number(el?.getAttribute?.('data-index')); - const isPinned = Boolean(el?.getAttribute?.('data-pinned')); - if (isPinned) { - const colId = table.getState().columnPinning.left[index]; - const column = table.getColumn(colId); - return column?.getSize() ?? 150; - } - const allCols = [...table.getLeftVisibleLeafColumns(), ...table.getCenterVisibleLeafColumns()] - return allCols[index]?.getSize() ?? 150; - }, - }), - enableRowSelection: true, - onRowSelectionChange: setRowSelection, - onColumnSizingChange: setColumnSizing, - onColumnPinningChange: setColumnPinning, - onGlobalFilterChange: handleGlobalFilterChange, - state: { - columnSizing, - columnPinning, - columnVisibility, - globalFilter, - showColumnFilters, - rowSelection, - editingCell, - }, - initialState: { - expanded: true, - }, - meta: tableMeta, - muiTableHeadCellProps: { - sx: { boxSizing: 'border-box' }, - }, - muiTableBodyCellProps: getTableBodyCellProps, - muiTableHeadProps: { - sx: { - display: 'table-header-group', - height: '1px', - minHeight: '1px', - maxHeight: '1px', - visibility: 'hidden', - '& svg': { - height: '1px', - minHeight: '1px', - maxHeight: '1px', - visibility: 'hidden', - } - }, - }, - muiTablePaperProps: getTablePaperStyles(), - muiTableContainerProps: { - ref: containerRef, - sx: { - position: 'relative', - contain: 'layout', - minHeight: '100%', - '& .MuiTable-root': { position: 'relative' }, - }, - }, - muiTableHeadCellFilterTextFieldProps: { - placeholder: 'Поиск...', - size: 'small', - }, - }); + const selectedColumnIdRef = useRef(selectedColumnId); - // Конфигурация таблицы - const tableConfig = useMemo(() => createTableConfig({ - columns, - data, - columnSizing, - columnPinning, - columnVisibility, - globalFilter, - showColumnFilters, - rowSelection, - containerRef, - tableMeta, - setColumnSizing, - setColumnPinning, - editingCell, - contextStartEditing, - }), [ - columns, - data, - columnSizing, - columnPinning, - columnVisibility, - globalFilter, - showColumnFilters, - rowSelection, - containerRef, - tableMeta, - setColumnSizing, - setColumnPinning, - editingCell, - ]); + useEffect(() => { + selectedColumnIdRef.current = selectedColumnId; + }, [selectedColumnId]); - const table = useMaterialReactTable(tableConfig); + const tableMeta = useMemo( + () => ({ + updateCell: handleUpdateCell, + getSelectedColumnId: () => selectedColumnIdRef.current, + }), + [handleUpdateCell], + ); - const handleNavigateToColumn = useCallback((columnId) => { - if (!columnId) return; + const ROW_VIRTUALIZER_OPTIONS = { + overscan: 5, + scrollPaddingStart: 0, + scrollPaddingEnd: 0, + estimateSize: () => TABLE_ROW_HEIGHT, + measureElement: (el) => el?.offsetHeight || TABLE_ROW_HEIGHT, + }; - setSelectedColumnId(columnId); + const createTableConfig = ({ + columns, + data, + columnSizing, + columnPinning, + columnVisibility, + globalFilter, + showColumnFilters, + rowSelection, + containerRef, + tableMeta, + setColumnSizing, + setColumnPinning, + editingCell, + contextStartEditing, + }) => ({ + ...BASE_TABLE_CONFIG, + columns, + data, + enableRowVirtualization: true, + enableColumnVirtualization: true, + rowVirtualizerInstanceRef: rowVirtualizerRef, + rowVirtualizerOptions: ROW_VIRTUALIZER_OPTIONS, + onEditingCellChange: (cell) => { + if (cell && !editingCell) { + contextStartEditing?.(cell.row, cell.column); + } + }, + columnVirtualizerOptions: ({ table }) => ({ + overscan: 10, + measureElement: (el) => { + if (!el) return 150; + const index = Number(el?.getAttribute?.('data-index')); + const isPinned = Boolean(el?.getAttribute?.('data-pinned')); + if (isPinned) { + const colId = table.getState().columnPinning.left[index]; + const column = table.getColumn(colId); + return column?.getSize() ?? 150; + } + const allCols = [...table.getLeftVisibleLeafColumns(), ...table.getCenterVisibleLeafColumns()]; + return allCols[index]?.getSize() ?? 150; + }, + }), + enableRowSelection: true, + onRowSelectionChange: setRowSelection, + onColumnSizingChange: setColumnSizing, + onColumnPinningChange: setColumnPinning, + onGlobalFilterChange: handleGlobalFilterChange, + state: { + columnSizing, + columnPinning, + columnVisibility, + globalFilter, + showColumnFilters, + rowSelection, + editingCell, + }, + initialState: { + expanded: true, + }, + meta: tableMeta, + muiTableHeadCellProps: { + sx: { boxSizing: 'border-box' }, + }, + muiTableBodyCellProps: getTableBodyCellProps, + muiTableHeadProps: { + sx: { + display: 'table-header-group', + height: '1px', + minHeight: '1px', + maxHeight: '1px', + visibility: 'hidden', + '& svg': { + height: '1px', + minHeight: '1px', + maxHeight: '1px', + visibility: 'hidden', + }, + }, + }, + muiTablePaperProps: getTablePaperStyles(), + muiTableContainerProps: { + ref: containerRef, + sx: { + position: 'relative', + contain: 'layout', + minHeight: '100%', + '& .MuiTable-root': { position: 'relative' }, + }, + }, + muiTableHeadCellFilterTextFieldProps: { + placeholder: 'Поиск...', + size: 'small', + }, + }); - const container = containerRef.current; - if (!container) return; + // Конфигурация таблицы + const tableConfig = useMemo( + () => + createTableConfig({ + columns, + data, + columnSizing, + columnPinning, + columnVisibility, + globalFilter, + showColumnFilters, + rowSelection, + containerRef, + tableMeta, + setColumnSizing, + setColumnPinning, + editingCell, + contextStartEditing, + }), + [ + columns, + data, + columnSizing, + columnPinning, + columnVisibility, + globalFilter, + showColumnFilters, + rowSelection, + containerRef, + tableMeta, + setColumnSizing, + setColumnPinning, + editingCell, + ], + ); - const pinnedIds = new Set(columnPinning?.left || []); - if (pinnedIds.has(columnId)) return; + const table = useMaterialReactTable(tableConfig); - const centerColumns = table - .getVisibleLeafColumns() - .filter((column) => !pinnedIds.has(column.id)); + const handleNavigateToColumn = useCallback( + (columnId) => { + if (!columnId) return; - let offset = 0; - for (const column of centerColumns) { - if (column.id === columnId) break; - offset += column.getSize(); - } + setSelectedColumnId(columnId); - container.scrollTo({ - left: Math.max(0, offset - 40), - behavior: 'smooth', - }); - }, [columnPinning, containerRef, table]); + const container = containerRef.current; + if (!container) return; - useEffect(() => { - if (!dataEditingCells?.line_id) { - setEditingCell(null); - return; - } - if (editingCell) return; + const pinnedIds = new Set(columnPinning?.left || []); + if (pinnedIds.has(columnId)) return; - // Отложить поиск до следующего тика - requestAnimationFrame(() => { - try { - const row = table.getRow(dataEditingCells.line_id); - const cell = row?.getVisibleCells().find( - c => c.column.id === dataEditingCells.column - ); - if (cell) setEditingCell(cell); - } catch (error) { - console.error(error); - } - }); - }, [dataEditingCells, editingCell, table]); + const centerColumns = table.getVisibleLeafColumns().filter((column) => !pinnedIds.has(column.id)); - const [isFirstLoad, setIsFirstLoad] = useState(true); + let offset = 0; + for (const column of centerColumns) { + if (column.id === columnId) break; + offset += column.getSize(); + } - useEffect(() => { - if (isFirstLoad && table && data && columns.length !== 0) { - setIsFirstLoad(false); - setIsLoadingData(true); - } - }, [data, columns, table, isFirstLoad]); + container.scrollTo({ + left: Math.max(0, offset - 40), + behavior: 'smooth', + }); + }, + [columnPinning, containerRef, table], + ); - const handleAddRow = useCallback(() => { - const allRows = table.getRowModel().rows; + useEffect(() => { + if (!dataEditingCells?.line_id) { + setEditingCell(null); + return; + } + if (editingCell) return; - const selectedRows = allRows.filter(row => rowSelection[row.id]); - if (selectedRows.length === 0) { - toast.error('Выделите строку для вставки'); - return; - } - const row = selectedRows[0]; - const expense_item_id = row.original.data.header.expense_item_id; - contextAddRow({ expense_item_id: expense_item_id }) - }, [rowSelection, table]) + // Отложить поиск до следующего тика + requestAnimationFrame(() => { + try { + const row = table.getRow(dataEditingCells.line_id); + const cell = row?.getVisibleCells().find((c) => c.column.id === dataEditingCells.column); + if (cell) setEditingCell(cell); + } catch (_error) {} + }); + }, [dataEditingCells, editingCell, table]); - const handleAddVspRow = useCallback((vsp_id) => { - contextAddRow({ vsp_id: vsp_id }); - }, []); + const [isFirstLoad, setIsFirstLoad] = useState(true); - const handleAddExpenseItemRow = useCallback((expense_item) => { - const allRows = table.getRowModel().rows; - const selectedRows = allRows.filter(row => rowSelection[row.id]); - const row = selectedRows[0]; - contextAddRow({ expense_item_id: expense_item.id, project_id: row.original.data.header.project_id }); - }, [rowSelection]); + useEffect(() => { + if (isFirstLoad && table && data && columns.length !== 0) { + setIsFirstLoad(false); + setIsLoadingData(true); + } + }, [data, columns, table, isFirstLoad]); - const handleAddProgramRow = useCallback((name) => { - contextAddProgram({ name: name }); - }, []); + const handleAddRow = useCallback(() => { + const allRows = table.getRowModel().rows; - const handleAddProjectRow = useCallback((name) => { - const allRows = table.getRowModel().rows; - const selectedRows = allRows.filter(row => rowSelection[row.id]); - const row = selectedRows[0]; - contextAddProject({ name: name, program_id: row.original.data.header.program_id }); - }, [rowSelection]); + const selectedRows = allRows.filter((row) => rowSelection[row.id]); + if (selectedRows.length === 0) { + toast.error('Выделите строку для вставки'); + return; + } + const row = selectedRows[0]; + const expense_item_id = row.original.data.header.expense_item_id; + contextAddRow({ expense_item_id: expense_item_id }); + }, [rowSelection, table]); - const handleOpenModalSelectVsp = useCallback(() => { - setIsOpenModalSelectVsp(true); - }, []) + const handleAddVspRow = useCallback((vsp_id) => { + contextAddRow({ vsp_id: vsp_id }); + }, []); - const handleOpenModalSelectExpenseItem = useCallback(() => { - const allRows = table.getRowModel().rows; + const handleAddExpenseItemRow = useCallback( + (expense_item) => { + const allRows = table.getRowModel().rows; + const selectedRows = allRows.filter((row) => rowSelection[row.id]); + const row = selectedRows[0]; + contextAddRow({ expense_item_id: expense_item.id, project_id: row.original.data.header.project_id }); + }, + [rowSelection], + ); - const selectedRows = allRows.filter(row => rowSelection[row.id]); - if (selectedRows.length === 0) { - toast.error('Выделите строку для вставки'); - return; - } - const row = selectedRows[0]; - if (row.original.row_type !== 'ITEM') { - toast.error('Выделите строку проекта'); - return; - } - setIsOpenModalSelectExpenseItem(true); - }, [rowSelection]) + const handleAddProgramRow = useCallback((name) => { + contextAddProgram({ name: name }); + }, []); - const handleDeleteRow = useCallback(() => { - const allRows = table.getRowModel().rows; + const handleAddProjectRow = useCallback( + (name) => { + const allRows = table.getRowModel().rows; + const selectedRows = allRows.filter((row) => rowSelection[row.id]); + const row = selectedRows[0]; + contextAddProject({ name: name, program_id: row.original.data.header.program_id }); + }, + [rowSelection], + ); - const selectedRows = allRows.filter(row => rowSelection[row.id]); - if (selectedRows.length === 0) { - toast.error('Выделите строку для удаления'); - return; - } - const row = selectedRows[0]; - const rowId = getRowId(row); - contextDeleteRow(rowId); - setRowSelection({}); - }, [rowSelection, table]) + const handleOpenModalSelectVsp = useCallback(() => { + setIsOpenModalSelectVsp(true); + }, []); - const addRow = useCallback(() => { + const handleOpenModalSelectExpenseItem = useCallback(() => { + const allRows = table.getRowModel().rows; - if (isVspAdditionRow) { - return handleOpenModalSelectVsp(); - } - if (isAdditionExpenseItem) { - return handleOpenModalSelectExpenseItem(); - } - return handleAddRow(); - }, [isVspAdditionRow, isAdditionExpenseItem, handleOpenModalSelectVsp, handleAddRow]); + const selectedRows = allRows.filter((row) => rowSelection[row.id]); + if (selectedRows.length === 0) { + toast.error('Выделите строку для вставки'); + return; + } + const row = selectedRows[0]; + if (row.original.row_type !== 'ITEM') { + toast.error('Выделите строку проекта'); + return; + } + setIsOpenModalSelectExpenseItem(true); + }, [rowSelection]); - const addProgram = useCallback(() => { - setIsProgramCreate(true); - setIsOpenModalCreateProgram(true); - }, [setIsOpenModalCreateProgram]) + const handleDeleteRow = useCallback(() => { + const allRows = table.getRowModel().rows; - const addProject = useCallback(() => { - setIsProgramCreate(false); - const allRows = table.getRowModel().rows; + const selectedRows = allRows.filter((row) => rowSelection[row.id]); + if (selectedRows.length === 0) { + toast.error('Выделите строку для удаления'); + return; + } + const row = selectedRows[0]; + const rowId = getRowId(row); + contextDeleteRow(rowId); + setRowSelection({}); + }, [rowSelection, table]); - const selectedRows = allRows.filter(row => rowSelection[row.id]); - if (selectedRows.length === 0) { - toast.error('Выделите строку для вставки'); - return; - } - const row = selectedRows[0]; - if (row.original.row_type !== 'GROUP') { - toast.error('Выделите строку программы'); - return; - } - setIsOpenModalCreateProgram(true); - }, [setIsOpenModalCreateProgram, rowSelection]) + const addRow = useCallback(() => { + if (isVspAdditionRow) { + return handleOpenModalSelectVsp(); + } + if (isAdditionExpenseItem) { + return handleOpenModalSelectExpenseItem(); + } + return handleAddRow(); + }, [isVspAdditionRow, isAdditionExpenseItem, handleOpenModalSelectVsp, handleAddRow]); - useEffect(() => { - return () => { - setData([]); - setRowSelection({}); - setEditingCell(null); - if (rowVirtualizerRef.current) { - rowVirtualizerRef.current = null; - } - }; - }, []); + const addProgram = useCallback(() => { + setIsProgramCreate(true); + setIsOpenModalCreateProgram(true); + }, [setIsOpenModalCreateProgram]); - return ( - <> - + const addProject = useCallback(() => { + setIsProgramCreate(false); + const allRows = table.getRowModel().rows; -
-
-
- + const selectedRows = allRows.filter((row) => rowSelection[row.id]); + if (selectedRows.length === 0) { + toast.error('Выделите строку для вставки'); + return; + } + const row = selectedRows[0]; + if (row.original.row_type !== 'GROUP') { + toast.error('Выделите строку программы'); + return; + } + setIsOpenModalCreateProgram(true); + }, [setIsOpenModalCreateProgram, rowSelection]); - + useEffect(() => { + return () => { + setData([]); + setRowSelection({}); + setEditingCell(null); + if (rowVirtualizerRef.current) { + rowVirtualizerRef.current = null; + } + }; + }, []); - {isTableLoading && ( -
- -
- )} + return ( + <> + - {headerPortalRef.current && - createPortal( - theme.zIndex.modal - 1 }} - selectedColumnId={selectedColumnId} - onColumnSelect={handleColumnSelect} - onChangeWidth={handleSetColumnWidth} - isLoadingData={isLoadingData} - />, - headerPortalRef.current, - )} -
-
-
- setIsOpenModalSelectVsp(false)} - formId={formId} - onSelect={handleAddVspRow} - title="Выбор ВСП" - /> - setIsOpenModalSelectExpenseItem(false)} - formId={formId} - onSelect={handleAddExpenseItemRow} - title="Добавление строки" - sheet={sheetName} - /> - setIsOpenModalCreateProgram(false)} - title={isProgramCreate ? "Создание программы" : "Создание проекта"} - onCreate={isProgramCreate ? handleAddProgramRow : handleAddProjectRow} - /> - - ); +
+
+
+ + + + + {isTableLoading && ( +
+ +
+ )} + + {headerPortalRef.current && + createPortal( + theme.zIndex.modal - 1 }} + selectedColumnId={selectedColumnId} + onColumnSelect={handleColumnSelect} + onChangeWidth={handleSetColumnWidth} + isLoadingData={isLoadingData} + />, + headerPortalRef.current, + )} +
+
+
+ setIsOpenModalSelectVsp(false)} + formId={formId} + onSelect={handleAddVspRow} + title='Выбор ВСП' + /> + setIsOpenModalSelectExpenseItem(false)} + formId={formId} + onSelect={handleAddExpenseItemRow} + title='Добавление строки' + sheet={sheetName} + /> + setIsOpenModalCreateProgram(false)} + title={isProgramCreate ? 'Создание программы' : 'Создание проекта'} + onCreate={isProgramCreate ? handleAddProgramRow : handleAddProjectRow} + /> + + ); }; -export default React.memo(RealtimeTable); \ No newline at end of file +export default React.memo(RealtimeTable); diff --git a/web/src/components/RealtimeTable/constants/FORM_2/AHR.js b/web/src/components/RealtimeTable/constants/FORM_2/AHR.js index a6cf4b5..d0dceb3 100644 --- a/web/src/components/RealtimeTable/constants/FORM_2/AHR.js +++ b/web/src/components/RealtimeTable/constants/FORM_2/AHR.js @@ -1,3200 +1,3194 @@ -import { - greenColumn, - whiteColumn, - orangeColumn, - yellowColumn, - redColumn, - blueColumn, -} from "../columnColors"; +import { blueColumn, greenColumn, orangeColumn, redColumn, whiteColumn, yellowColumn } from '../columnColors'; export const config = { - config: { - colors: { - "data.header.section_code": { - color_type: greenColumn, - accessorKey: "data.header.section_code", - }, - "data.header.item_id": { - color_type: greenColumn, - accessorKey: "data.header.item_id", - }, - "data.header.num_group": { - color_type: greenColumn, - accessorKey: "data.header.num_group", - }, - "data.header.name": { - color_type: greenColumn, - accessorKey: "data.header.name", - }, - "data.header.vsp_id": { - color_type: greenColumn, - accessorKey: "data.header.vsp_id", - }, - "data.plan.q1": { - color_type: greenColumn, - accessorKey: "data.plan.q1", - }, - "data.plan.q2": { - color_type: greenColumn, - accessorKey: "data.plan.q2", - }, - "data.plan.q3": { - color_type: greenColumn, - accessorKey: "data.plan.q3", - }, - "data.plan.q4": { - color_type: greenColumn, - accessorKey: "data.plan.q4", - }, - "data.plan.year": { - color_type: greenColumn, - accessorKey: "data.plan.year", - }, - "data.plan.comment": { - color_type: greenColumn, - accessorKey: "data.plan.comment", - }, - "2026_god_field_field": { - color_type: whiteColumn, - accessorKey: "2026_god_field_field", - }, - "data.seq_dfip.q1": { - color_type: greenColumn, - accessorKey: "data.seq_dfip.q1", - }, - "data.seq_dfip.q2": { - color_type: greenColumn, - accessorKey: "data.seq_dfip.q2", - }, - "data.seq_dfip.q3": { - color_type: greenColumn, - accessorKey: "data.seq_dfip.q3", - }, - "data.seq_dfip.q4": { - color_type: greenColumn, - accessorKey: "data.seq_dfip.q4", - }, - "data.seq_dfip.year": { - color_type: greenColumn, - accessorKey: "data.seq_dfip.year", - }, - "data.seq_dfip.justification": { - color_type: greenColumn, - accessorKey: "data.seq_dfip.justification", - }, - "data.seq_ssp.q1": { - color_type: greenColumn, - accessorKey: "data.seq_ssp.q1", - }, - "data.seq_ssp.q2": { - color_type: greenColumn, - accessorKey: "data.seq_ssp.q2", - }, - "data.seq_ssp.q3": { - color_type: greenColumn, - accessorKey: "data.seq_ssp.q3", - }, - "data.seq_ssp.q4": { - color_type: greenColumn, - accessorKey: "data.seq_ssp.q4", - }, - "data.seq_ssp.year": { - color_type: greenColumn, - accessorKey: "data.seq_ssp.year", - }, - "data.seq_ssp.justification": { - color_type: greenColumn, - accessorKey: "data.seq_ssp.justification", - }, - "data.approved.q1": { - color_type: greenColumn, - accessorKey: "data.approved.q1", - }, - "data.approved.q2": { - color_type: greenColumn, - accessorKey: "data.approved.q2", - }, - "data.approved.q3": { - color_type: greenColumn, - accessorKey: "data.approved.q3", - }, - "data.approved.q4": { - color_type: greenColumn, - accessorKey: "data.approved.q4", - }, - "data.approved.year": { - color_type: greenColumn, - accessorKey: "data.approved.year", - }, - "data.contract.counterparty": { - color_type: orangeColumn, - accessorKey: "data.contract.counterparty", - }, - "data.contract.reference": { - color_type: orangeColumn, - accessorKey: "data.contract.reference", - }, - "data.contract.date": { - color_type: orangeColumn, - accessorKey: "data.contract.date", - }, - "data.contract.subject": { - color_type: orangeColumn, - accessorKey: "data.contract.subject", - }, - "data.contract.currency": { - color_type: orangeColumn, - accessorKey: "data.contract.currency", - }, - "data.contract.ceiling": { - color_type: orangeColumn, - accessorKey: "data.contract.ceiling", - }, - "data.contract.vat_rate": { - color_type: orangeColumn, - accessorKey: "data.contract.vat_rate", - }, - "data.contract.deadline": { - color_type: orangeColumn, - accessorKey: "data.contract.deadline", - }, - "data.contract.scheme": { - color_type: orangeColumn, - accessorKey: "data.contract.scheme", - }, - "data.contract.act": { - color_type: orangeColumn, - accessorKey: "data.contract.act", - }, - "data.contract.comment": { - color_type: orangeColumn, - accessorKey: "data.contract.comment", - }, - "data.booking.y2026.q1": { - color_type: orangeColumn, - accessorKey: "data.booking.y2026.q1", - }, - "data.booking.y2026.q2": { - color_type: orangeColumn, - accessorKey: "data.booking.y2026.q2", - }, - "data.booking.y2026.q3": { - color_type: orangeColumn, - accessorKey: "data.booking.y2026.q3", - }, - "data.booking.y2026.q4": { - color_type: orangeColumn, - accessorKey: "data.booking.y2026.q4", - }, - "data.booking.y2027.q1": { - color_type: orangeColumn, - accessorKey: "data.booking.y2027.q1", - }, - "data.booking.y2027.q2": { - color_type: orangeColumn, - accessorKey: "data.booking.y2027.q2", - }, - "data.booking.y2027.q3": { - color_type: orangeColumn, - accessorKey: "data.booking.y2027.q3", - }, - "data.booking.y2027.q4": { - color_type: orangeColumn, - accessorKey: "data.booking.y2027.q4", - }, - "data.q1.adj_current": { - color_type: yellowColumn, - accessorKey: "data.q1.adj_current", - }, - "data.q1.adj_ssp": { - color_type: yellowColumn, - accessorKey: "data.q1.adj_ssp", - }, - "data.q1.adj_reserve": { - color_type: yellowColumn, - accessorKey: "data.q1.adj_reserve", - }, - "data.q1.adj_comment": { - color_type: yellowColumn, - accessorKey: "data.q1.adj_comment", - }, - "data.q1.corrected_plan": { - color_type: yellowColumn, - accessorKey: "data.q1.corrected_plan", - }, - "1_kvartal_2026_goda_field_field": { - color_type: whiteColumn, - accessorKey: "1_kvartal_2026_goda_field_field", - }, - "data.q1.pay_date": { - color_type: blueColumn, - accessorKey: "data.q1.pay_date", - }, - "data.q1.pay_amount": { - color_type: blueColumn, - accessorKey: "data.q1.pay_amount", - }, - "data.q1.pay_comment": { - color_type: blueColumn, - accessorKey: "data.q1.pay_comment", - }, - "data.q1.pay_act": { - color_type: blueColumn, - accessorKey: "data.q1.pay_act", - }, - "data.q1.booking": { - color_type: orangeColumn, - accessorKey: "data.q1.booking", - }, - "data.q1.actual_m1": { - color_type: greenColumn, - accessorKey: "data.q1.actual_m1", - }, - "data.q1.actual_m2": { - color_type: greenColumn, - accessorKey: "data.q1.actual_m2", - }, - "data.q1.actual_m3": { - color_type: greenColumn, - accessorKey: "data.q1.actual_m3", - }, - "data.q1.actual_quarter": { - color_type: greenColumn, - accessorKey: "data.q1.actual_quarter", - }, - "data.q1.residual_after_booking": { - color_type: orangeColumn, - accessorKey: "data.q1.residual_after_booking", - }, - "data.q1.residual_after_actual": { - color_type: greenColumn, - accessorKey: "data.q1.residual_after_actual", - }, - "data.q1.transfer_q2": { - color_type: redColumn, - accessorKey: "data.q1.transfer_q2", - }, - "data.q1.transfer_q2_delay_acts": { - color_type: redColumn, - accessorKey: "data.q1.transfer_q2_delay_acts", - }, - "data.q1.transfer_q2_delay_procurement": { - color_type: redColumn, - accessorKey: "data.q1.transfer_q2_delay_procurement", - }, - "data.q1.transfer_q2_economy_rf": { - color_type: redColumn, - accessorKey: "data.q1.transfer_q2_economy_rf", - }, - "data.q1.transfer_next_comment": { - color_type: redColumn, - accessorKey: "data.q1.transfer_next_comment", - }, - "data.q1.transfer_q3": { - color_type: redColumn, - accessorKey: "data.q1.transfer_q3", - }, - "data.q1.transfer_q4": { - color_type: redColumn, - accessorKey: "data.q1.transfer_q4", - }, - "data.q1.transfer_far_comment": { - color_type: redColumn, - accessorKey: "data.q1.transfer_far_comment", - }, - "data.q1.transfer_econ": { - color_type: redColumn, - accessorKey: "data.q1.transfer_econ", - }, - "data.q1.total": { - color_type: redColumn, - accessorKey: "data.q1.total", - }, - "data.q2.target_change": { - color_type: redColumn, - accessorKey: "data.q2.target_change", - }, - "data.q2.base_correction": { - color_type: redColumn, - accessorKey: "data.q2.base_correction", - }, - "data.q2.base_correction_comment": { - color_type: redColumn, - accessorKey: "data.q2.base_correction_comment", - }, - "data.q2.revision_inc": { - color_type: yellowColumn, - accessorKey: "data.q2.revision_inc", - }, - "data.q2.revision_seq": { - color_type: yellowColumn, - accessorKey: "data.q2.revision_seq", - }, - "data.q2.revision_comment": { - color_type: yellowColumn, - accessorKey: "data.q2.revision_comment", - }, - "data.q2.new_plan": { - color_type: yellowColumn, - accessorKey: "data.q2.new_plan", - }, - "2_kvartal_2026_goda_field_field": { - color_type: whiteColumn, - accessorKey: "2_kvartal_2026_goda_field_field", - }, - "data.q2.adj_current": { - color_type: yellowColumn, - accessorKey: "data.q2.adj_current", - }, - "data.q2.adj_ssp": { - color_type: yellowColumn, - accessorKey: "data.q2.adj_ssp", - }, - "data.q2.adj_reserve": { - color_type: yellowColumn, - accessorKey: "data.q2.adj_reserve", - }, - "data.q2.adj_comment": { - color_type: yellowColumn, - accessorKey: "data.q2.adj_comment", - }, - "data.q2.corrected_plan": { - color_type: yellowColumn, - accessorKey: "data.q2.corrected_plan", - }, - "data.q2.pay_date": { - color_type: blueColumn, - accessorKey: "data.q2.pay_date", - }, - "data.q2.pay_amount": { - color_type: blueColumn, - accessorKey: "data.q2.pay_amount", - }, - "data.q2.pay_comment": { - color_type: blueColumn, - accessorKey: "data.q2.pay_comment", - }, - "data.q2.pay_act": { - color_type: blueColumn, - accessorKey: "data.q2.pay_act", - }, - "data.q2.booking": { - color_type: orangeColumn, - accessorKey: "data.q2.booking", - }, - "data.q2.actual_m1": { - color_type: greenColumn, - accessorKey: "data.q2.actual_m1", - }, - "data.q2.actual_m2": { - color_type: greenColumn, - accessorKey: "data.q2.actual_m2", - }, - "data.q2.actual_m3": { - color_type: greenColumn, - accessorKey: "data.q2.actual_m3", - }, - "data.q2.actual_quarter": { - color_type: greenColumn, - accessorKey: "data.q2.actual_quarter", - }, - "data.q2.residual_after_booking": { - color_type: orangeColumn, - accessorKey: "data.q2.residual_after_booking", - }, - "data.q2.residual_after_actual": { - color_type: greenColumn, - accessorKey: "data.q2.residual_after_actual", - }, - "data.q2.transfer_q3": { - color_type: redColumn, - accessorKey: "data.q2.transfer_q3", - }, - "data.q2.transfer_q3_delay_acts": { - color_type: redColumn, - accessorKey: "data.q2.transfer_q3_delay_acts", - }, - "data.q2.transfer_q3_delay_procurement": { - color_type: redColumn, - accessorKey: "data.q2.transfer_q3_delay_procurement", - }, - "data.q2.transfer_q3_economy_rf": { - color_type: redColumn, - accessorKey: "data.q2.transfer_q3_economy_rf", - }, - "data.q2.transfer_next_comment": { - color_type: redColumn, - accessorKey: "data.q2.transfer_next_comment", - }, - "data.q2.transfer_q4": { - color_type: redColumn, - accessorKey: "data.q2.transfer_q4", - }, - "data.q2.transfer_far_comment": { - color_type: redColumn, - accessorKey: "data.q2.transfer_far_comment", - }, - "data.q2.transfer_econ": { - color_type: redColumn, - accessorKey: "data.q2.transfer_econ", - }, - "data.q2.total": { - color_type: redColumn, - accessorKey: "data.q2.total", - }, - "data.q3.target_change": { - color_type: redColumn, - accessorKey: "data.q3.target_change", - }, - "data.q3.base_correction": { - color_type: redColumn, - accessorKey: "data.q3.base_correction", - }, - "data.q3.base_correction_comment": { - color_type: redColumn, - accessorKey: "data.q3.base_correction_comment", - }, - "data.q3.revision_inc": { - color_type: yellowColumn, - accessorKey: "data.q3.revision_inc", - }, - "data.q3.revision_seq": { - color_type: yellowColumn, - accessorKey: "data.q3.revision_seq", - }, - "data.q3.revision_comment": { - color_type: yellowColumn, - accessorKey: "data.q3.revision_comment", - }, - "data.q3.new_plan": { - color_type: yellowColumn, - accessorKey: "data.q3.new_plan", - }, - "3_kvartal_2026_goda_field_field": { - color_type: whiteColumn, - accessorKey: "3_kvartal_2026_goda_field_field", - }, - "data.q3.adj_current": { - color_type: yellowColumn, - accessorKey: "data.q3.adj_current", - }, - "data.q3.adj_ssp": { - color_type: yellowColumn, - accessorKey: "data.q3.adj_ssp", - }, - "data.q3.adj_reserve": { - color_type: yellowColumn, - accessorKey: "data.q3.adj_reserve", - }, - "data.q3.adj_comment": { - color_type: yellowColumn, - accessorKey: "data.q3.adj_comment", - }, - "data.q3.corrected_plan": { - color_type: yellowColumn, - accessorKey: "data.q3.corrected_plan", - }, - "data.q3.pay_date": { - color_type: blueColumn, - accessorKey: "data.q3.pay_date", - }, - "data.q3.pay_amount": { - color_type: blueColumn, - accessorKey: "data.q3.pay_amount", - }, - "data.q3.pay_comment": { - color_type: blueColumn, - accessorKey: "data.q3.pay_comment", - }, - "data.q3.pay_act": { - color_type: blueColumn, - accessorKey: "data.q3.pay_act", - }, - "data.q3.booking": { - color_type: orangeColumn, - accessorKey: "data.q3.booking", - }, - "data.q3.actual_m1": { - color_type: greenColumn, - accessorKey: "data.q3.actual_m1", - }, - "data.q3.actual_m2": { - color_type: greenColumn, - accessorKey: "data.q3.actual_m2", - }, - "data.q3.actual_m3": { - color_type: greenColumn, - accessorKey: "data.q3.actual_m3", - }, - "data.q3.actual_quarter": { - color_type: greenColumn, - accessorKey: "data.q3.actual_quarter", - }, - "data.q3.residual_after_booking": { - color_type: orangeColumn, - accessorKey: "data.q3.residual_after_booking", - }, - "data.q3.residual_after_actual": { - color_type: greenColumn, - accessorKey: "data.q3.residual_after_actual", - }, - "data.q3.transfer_q4": { - color_type: redColumn, - accessorKey: "data.q3.transfer_q4", - }, - "data.q3.transfer_q4_delay_acts": { - color_type: redColumn, - accessorKey: "data.q3.transfer_q4_delay_acts", - }, - "data.q3.transfer_q4_delay_procurement": { - color_type: redColumn, - accessorKey: "data.q3.transfer_q4_delay_procurement", - }, - "data.q3.transfer_q4_economy_rf": { - color_type: redColumn, - accessorKey: "data.q3.transfer_q4_economy_rf", - }, - "data.q3.transfer_next_comment": { - color_type: redColumn, - accessorKey: "data.q3.transfer_next_comment", - }, - "data.q3.transfer_econ": { - color_type: redColumn, - accessorKey: "data.q3.transfer_econ", - }, - "data.q3.total": { - color_type: redColumn, - accessorKey: "data.q3.total", - }, - "data.q4.target_change": { - color_type: redColumn, - accessorKey: "data.q4.target_change", - }, - "data.q4.base_correction": { - color_type: redColumn, - accessorKey: "data.q4.base_correction", - }, - "data.q4.base_correction_comment": { - color_type: redColumn, - accessorKey: "data.q4.base_correction_comment", - }, - "data.q4.revision_inc": { - color_type: yellowColumn, - accessorKey: "data.q4.revision_inc", - }, - "data.q4.revision_seq": { - color_type: yellowColumn, - accessorKey: "data.q4.revision_seq", - }, - "data.q4.revision_comment": { - color_type: yellowColumn, - accessorKey: "data.q4.revision_comment", - }, - "data.q4.new_plan": { - color_type: yellowColumn, - accessorKey: "data.q4.new_plan", - }, - "4_kvartal_2026_goda_field_field": { - color_type: whiteColumn, - accessorKey: "4_kvartal_2026_goda_field_field", - }, - "data.q4.adj_current": { - color_type: yellowColumn, - accessorKey: "data.q4.adj_current", - }, - "data.q4.adj_ssp": { - color_type: yellowColumn, - accessorKey: "data.q4.adj_ssp", - }, - "data.q4.adj_reserve": { - color_type: yellowColumn, - accessorKey: "data.q4.adj_reserve", - }, - "data.q4.adj_comment": { - color_type: yellowColumn, - accessorKey: "data.q4.adj_comment", - }, - "data.q4.corrected_plan": { - color_type: yellowColumn, - accessorKey: "data.q4.corrected_plan", - }, - "data.q4.pay_date": { - color_type: blueColumn, - accessorKey: "data.q4.pay_date", - }, - "data.q4.pay_amount": { - color_type: blueColumn, - accessorKey: "data.q4.pay_amount", - }, - "data.q4.pay_comment": { - color_type: blueColumn, - accessorKey: "data.q4.pay_comment", - }, - "data.q4.pay_act": { - color_type: blueColumn, - accessorKey: "data.q4.pay_act", - }, - "data.q4.booking": { - color_type: orangeColumn, - accessorKey: "data.q4.booking", - }, - "data.q4.actual_m1": { - color_type: greenColumn, - accessorKey: "data.q4.actual_m1", - }, - "data.q4.actual_m2": { - color_type: greenColumn, - accessorKey: "data.q4.actual_m2", - }, - "data.q4.actual_m3": { - color_type: greenColumn, - accessorKey: "data.q4.actual_m3", - }, - "data.q4.actual_spod": { - color_type: greenColumn, - accessorKey: "data.q4.actual_spod", - }, - "data.q4.actual_quarter": { - color_type: greenColumn, - accessorKey: "data.q4.actual_quarter", - }, - "data.q4.residual_after_booking": { - color_type: orangeColumn, - accessorKey: "data.q4.residual_after_booking", - }, - "data.q4.residual_after_actual": { - color_type: greenColumn, - accessorKey: "data.q4.residual_after_actual", - }, - "data.q4.transfer_econ": { - color_type: redColumn, - accessorKey: "data.q4.transfer_econ", - }, - "data.totals.fact_year": { - color_type: greenColumn, - accessorKey: "data.totals.fact_year", - }, - "2026_god_field_field_5": { - color_type: whiteColumn, - accessorKey: "2026_god_field_field_5", - }, - "data.totals.pay_year": { - color_type: blueColumn, - accessorKey: "data.totals.pay_year", - }, - }, - columns: [ - { - header: " ", - accessorKey: "field", - columns: [ - { - header: " ", - accessorKey: "field_field", - columns: [ - { - header: "Код раздела", - accessorKey: "data.header.section_code", - columnLetter: "A", - size: 150, - filterFn: "contains", - }, - { - header: "ID статьи", - accessorKey: "data.header.item_id", - columnLetter: "B", - size: 150, - filterFn: "contains", - }, - { - header: "ID группы номенклатуры", - accessorKey: "data.header.num_group", - columnLetter: "C", - size: 220, - filterFn: "contains", - }, - { - header: "Наименование", - accessorKey: "data.header.name", - columnLetter: "D", - size: 150, - filterFn: "contains", - }, - { - header: "ВСП РФ", - accessorKey: "data.header.vsp_id", - columnLetter: "E", - size: 150, - filterFn: "contains", - }, - ], - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - ], - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - { - header: "2026 год", - accessorKey: "2026_god", - columns: [ - { - header: "Планирование годовых показателей", - accessorKey: "2026_god_planirovanie_godovykh_pokazateley", - columns: [ - { - header: "1 квартал", - accessorKey: "data.plan.q1", - columnLetter: "F", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - { - header: "2 квартал", - accessorKey: "data.plan.q2", - columnLetter: "G", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - { - header: "3 квартал", - accessorKey: "data.plan.q3", - columnLetter: "H", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - { - header: "4 квартал", - accessorKey: "data.plan.q4", - columnLetter: "I", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - { - header: "Год", - accessorKey: "data.plan.year", - columnLetter: "J", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - { - header: "Комментарий", - accessorKey: "data.plan.comment", - columnLetter: "K", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - ], - muiTableHeadCellProps: { - sx: { - backgroundColor: "#B2A1C7", - color: "#000000", - }, - }, - }, + config: { + colors: { + 'data.header.section_code': { + color_type: greenColumn, + accessorKey: 'data.header.section_code', + }, + 'data.header.item_id': { + color_type: greenColumn, + accessorKey: 'data.header.item_id', + }, + 'data.header.num_group': { + color_type: greenColumn, + accessorKey: 'data.header.num_group', + }, + 'data.header.name': { + color_type: greenColumn, + accessorKey: 'data.header.name', + }, + 'data.header.vsp_id': { + color_type: greenColumn, + accessorKey: 'data.header.vsp_id', + }, + 'data.header.vsp_address': { + color_type: greenColumn, + accessorKey: 'data.header.vsp_address', + }, + 'data.plan.q1': { + color_type: greenColumn, + accessorKey: 'data.plan.q1', + }, + 'data.plan.q2': { + color_type: greenColumn, + accessorKey: 'data.plan.q2', + }, + 'data.plan.q3': { + color_type: greenColumn, + accessorKey: 'data.plan.q3', + }, + 'data.plan.q4': { + color_type: greenColumn, + accessorKey: 'data.plan.q4', + }, + 'data.plan.year': { + color_type: greenColumn, + accessorKey: 'data.plan.year', + }, + 'data.plan.comment': { + color_type: greenColumn, + accessorKey: 'data.plan.comment', + }, + '2026_god_field_field': { + color_type: whiteColumn, + accessorKey: '2026_god_field_field', + }, + 'data.seq_dfip.q1': { + color_type: greenColumn, + accessorKey: 'data.seq_dfip.q1', + }, + 'data.seq_dfip.q2': { + color_type: greenColumn, + accessorKey: 'data.seq_dfip.q2', + }, + 'data.seq_dfip.q3': { + color_type: greenColumn, + accessorKey: 'data.seq_dfip.q3', + }, + 'data.seq_dfip.q4': { + color_type: greenColumn, + accessorKey: 'data.seq_dfip.q4', + }, + 'data.seq_dfip.year': { + color_type: greenColumn, + accessorKey: 'data.seq_dfip.year', + }, + 'data.seq_dfip.justification': { + color_type: greenColumn, + accessorKey: 'data.seq_dfip.justification', + }, + 'data.seq_ssp.q1': { + color_type: greenColumn, + accessorKey: 'data.seq_ssp.q1', + }, + 'data.seq_ssp.q2': { + color_type: greenColumn, + accessorKey: 'data.seq_ssp.q2', + }, + 'data.seq_ssp.q3': { + color_type: greenColumn, + accessorKey: 'data.seq_ssp.q3', + }, + 'data.seq_ssp.q4': { + color_type: greenColumn, + accessorKey: 'data.seq_ssp.q4', + }, + 'data.seq_ssp.year': { + color_type: greenColumn, + accessorKey: 'data.seq_ssp.year', + }, + 'data.seq_ssp.justification': { + color_type: greenColumn, + accessorKey: 'data.seq_ssp.justification', + }, + 'data.approved.q1': { + color_type: greenColumn, + accessorKey: 'data.approved.q1', + }, + 'data.approved.q2': { + color_type: greenColumn, + accessorKey: 'data.approved.q2', + }, + 'data.approved.q3': { + color_type: greenColumn, + accessorKey: 'data.approved.q3', + }, + 'data.approved.q4': { + color_type: greenColumn, + accessorKey: 'data.approved.q4', + }, + 'data.approved.year': { + color_type: greenColumn, + accessorKey: 'data.approved.year', + }, + 'data.contract.counterparty': { + color_type: orangeColumn, + accessorKey: 'data.contract.counterparty', + }, + 'data.contract.reference': { + color_type: orangeColumn, + accessorKey: 'data.contract.reference', + }, + 'data.contract.date': { + color_type: orangeColumn, + accessorKey: 'data.contract.date', + }, + 'data.contract.subject': { + color_type: orangeColumn, + accessorKey: 'data.contract.subject', + }, + 'data.contract.currency': { + color_type: orangeColumn, + accessorKey: 'data.contract.currency', + }, + 'data.contract.ceiling': { + color_type: orangeColumn, + accessorKey: 'data.contract.ceiling', + }, + 'data.contract.vat_rate': { + color_type: orangeColumn, + accessorKey: 'data.contract.vat_rate', + }, + 'data.contract.deadline': { + color_type: orangeColumn, + accessorKey: 'data.contract.deadline', + }, + 'data.contract.scheme': { + color_type: orangeColumn, + accessorKey: 'data.contract.scheme', + }, + 'data.contract.act': { + color_type: orangeColumn, + accessorKey: 'data.contract.act', + }, + 'data.contract.comment': { + color_type: orangeColumn, + accessorKey: 'data.contract.comment', + }, + 'data.booking.y2026.q1': { + color_type: orangeColumn, + accessorKey: 'data.booking.y2026.q1', + }, + 'data.booking.y2026.q2': { + color_type: orangeColumn, + accessorKey: 'data.booking.y2026.q2', + }, + 'data.booking.y2026.q3': { + color_type: orangeColumn, + accessorKey: 'data.booking.y2026.q3', + }, + 'data.booking.y2026.q4': { + color_type: orangeColumn, + accessorKey: 'data.booking.y2026.q4', + }, + 'data.booking.y2027.q1': { + color_type: orangeColumn, + accessorKey: 'data.booking.y2027.q1', + }, + 'data.booking.y2027.q2': { + color_type: orangeColumn, + accessorKey: 'data.booking.y2027.q2', + }, + 'data.booking.y2027.q3': { + color_type: orangeColumn, + accessorKey: 'data.booking.y2027.q3', + }, + 'data.booking.y2027.q4': { + color_type: orangeColumn, + accessorKey: 'data.booking.y2027.q4', + }, + 'data.q1.adj_current': { + color_type: yellowColumn, + accessorKey: 'data.q1.adj_current', + }, + 'data.q1.adj_ssp': { + color_type: yellowColumn, + accessorKey: 'data.q1.adj_ssp', + }, + 'data.q1.adj_reserve': { + color_type: yellowColumn, + accessorKey: 'data.q1.adj_reserve', + }, + 'data.q1.adj_comment': { + color_type: yellowColumn, + accessorKey: 'data.q1.adj_comment', + }, + 'data.q1.corrected_plan': { + color_type: yellowColumn, + accessorKey: 'data.q1.corrected_plan', + }, + '1_kvartal_2026_goda_field_field': { + color_type: whiteColumn, + accessorKey: '1_kvartal_2026_goda_field_field', + }, + 'data.q1.pay_date': { + color_type: blueColumn, + accessorKey: 'data.q1.pay_date', + }, + 'data.q1.pay_amount': { + color_type: blueColumn, + accessorKey: 'data.q1.pay_amount', + }, + 'data.q1.pay_comment': { + color_type: blueColumn, + accessorKey: 'data.q1.pay_comment', + }, + 'data.q1.pay_act': { + color_type: blueColumn, + accessorKey: 'data.q1.pay_act', + }, + 'data.q1.booking': { + color_type: orangeColumn, + accessorKey: 'data.q1.booking', + }, + 'data.q1.actual_m1': { + color_type: greenColumn, + accessorKey: 'data.q1.actual_m1', + }, + 'data.q1.actual_m2': { + color_type: greenColumn, + accessorKey: 'data.q1.actual_m2', + }, + 'data.q1.actual_m3': { + color_type: greenColumn, + accessorKey: 'data.q1.actual_m3', + }, + 'data.q1.actual_quarter': { + color_type: greenColumn, + accessorKey: 'data.q1.actual_quarter', + }, + 'data.q1.residual_after_booking': { + color_type: orangeColumn, + accessorKey: 'data.q1.residual_after_booking', + }, + 'data.q1.residual_after_actual': { + color_type: greenColumn, + accessorKey: 'data.q1.residual_after_actual', + }, + 'data.q1.transfer_q2': { + color_type: redColumn, + accessorKey: 'data.q1.transfer_q2', + }, + 'data.q1.transfer_q2_delay_acts': { + color_type: redColumn, + accessorKey: 'data.q1.transfer_q2_delay_acts', + }, + 'data.q1.transfer_q2_delay_procurement': { + color_type: redColumn, + accessorKey: 'data.q1.transfer_q2_delay_procurement', + }, + 'data.q1.transfer_q2_economy_rf': { + color_type: redColumn, + accessorKey: 'data.q1.transfer_q2_economy_rf', + }, + 'data.q1.transfer_next_comment': { + color_type: redColumn, + accessorKey: 'data.q1.transfer_next_comment', + }, + 'data.q1.transfer_q3': { + color_type: redColumn, + accessorKey: 'data.q1.transfer_q3', + }, + 'data.q1.transfer_q4': { + color_type: redColumn, + accessorKey: 'data.q1.transfer_q4', + }, + 'data.q1.transfer_far_comment': { + color_type: redColumn, + accessorKey: 'data.q1.transfer_far_comment', + }, + 'data.q1.transfer_econ': { + color_type: redColumn, + accessorKey: 'data.q1.transfer_econ', + }, + 'data.q1.total': { + color_type: redColumn, + accessorKey: 'data.q1.total', + }, + 'data.q2.target_change': { + color_type: redColumn, + accessorKey: 'data.q2.target_change', + }, + 'data.q2.base_correction': { + color_type: redColumn, + accessorKey: 'data.q2.base_correction', + }, + 'data.q2.base_correction_comment': { + color_type: redColumn, + accessorKey: 'data.q2.base_correction_comment', + }, + 'data.q2.revision_inc': { + color_type: yellowColumn, + accessorKey: 'data.q2.revision_inc', + }, + 'data.q2.revision_seq': { + color_type: yellowColumn, + accessorKey: 'data.q2.revision_seq', + }, + 'data.q2.revision_comment': { + color_type: yellowColumn, + accessorKey: 'data.q2.revision_comment', + }, + 'data.q2.new_plan': { + color_type: yellowColumn, + accessorKey: 'data.q2.new_plan', + }, + '2_kvartal_2026_goda_field_field': { + color_type: whiteColumn, + accessorKey: '2_kvartal_2026_goda_field_field', + }, + 'data.q2.adj_current': { + color_type: yellowColumn, + accessorKey: 'data.q2.adj_current', + }, + 'data.q2.adj_ssp': { + color_type: yellowColumn, + accessorKey: 'data.q2.adj_ssp', + }, + 'data.q2.adj_reserve': { + color_type: yellowColumn, + accessorKey: 'data.q2.adj_reserve', + }, + 'data.q2.adj_comment': { + color_type: yellowColumn, + accessorKey: 'data.q2.adj_comment', + }, + 'data.q2.corrected_plan': { + color_type: yellowColumn, + accessorKey: 'data.q2.corrected_plan', + }, + 'data.q2.pay_date': { + color_type: blueColumn, + accessorKey: 'data.q2.pay_date', + }, + 'data.q2.pay_amount': { + color_type: blueColumn, + accessorKey: 'data.q2.pay_amount', + }, + 'data.q2.pay_comment': { + color_type: blueColumn, + accessorKey: 'data.q2.pay_comment', + }, + 'data.q2.pay_act': { + color_type: blueColumn, + accessorKey: 'data.q2.pay_act', + }, + 'data.q2.booking': { + color_type: orangeColumn, + accessorKey: 'data.q2.booking', + }, + 'data.q2.actual_m1': { + color_type: greenColumn, + accessorKey: 'data.q2.actual_m1', + }, + 'data.q2.actual_m2': { + color_type: greenColumn, + accessorKey: 'data.q2.actual_m2', + }, + 'data.q2.actual_m3': { + color_type: greenColumn, + accessorKey: 'data.q2.actual_m3', + }, + 'data.q2.actual_quarter': { + color_type: greenColumn, + accessorKey: 'data.q2.actual_quarter', + }, + 'data.q2.residual_after_booking': { + color_type: orangeColumn, + accessorKey: 'data.q2.residual_after_booking', + }, + 'data.q2.residual_after_actual': { + color_type: greenColumn, + accessorKey: 'data.q2.residual_after_actual', + }, + 'data.q2.transfer_q3': { + color_type: redColumn, + accessorKey: 'data.q2.transfer_q3', + }, + 'data.q2.transfer_q3_delay_acts': { + color_type: redColumn, + accessorKey: 'data.q2.transfer_q3_delay_acts', + }, + 'data.q2.transfer_q3_delay_procurement': { + color_type: redColumn, + accessorKey: 'data.q2.transfer_q3_delay_procurement', + }, + 'data.q2.transfer_q3_economy_rf': { + color_type: redColumn, + accessorKey: 'data.q2.transfer_q3_economy_rf', + }, + 'data.q2.transfer_next_comment': { + color_type: redColumn, + accessorKey: 'data.q2.transfer_next_comment', + }, + 'data.q2.transfer_q4': { + color_type: redColumn, + accessorKey: 'data.q2.transfer_q4', + }, + 'data.q2.transfer_far_comment': { + color_type: redColumn, + accessorKey: 'data.q2.transfer_far_comment', + }, + 'data.q2.transfer_econ': { + color_type: redColumn, + accessorKey: 'data.q2.transfer_econ', + }, + 'data.q2.total': { + color_type: redColumn, + accessorKey: 'data.q2.total', + }, + 'data.q3.target_change': { + color_type: redColumn, + accessorKey: 'data.q3.target_change', + }, + 'data.q3.base_correction': { + color_type: redColumn, + accessorKey: 'data.q3.base_correction', + }, + 'data.q3.base_correction_comment': { + color_type: redColumn, + accessorKey: 'data.q3.base_correction_comment', + }, + 'data.q3.revision_inc': { + color_type: yellowColumn, + accessorKey: 'data.q3.revision_inc', + }, + 'data.q3.revision_seq': { + color_type: yellowColumn, + accessorKey: 'data.q3.revision_seq', + }, + 'data.q3.revision_comment': { + color_type: yellowColumn, + accessorKey: 'data.q3.revision_comment', + }, + 'data.q3.new_plan': { + color_type: yellowColumn, + accessorKey: 'data.q3.new_plan', + }, + '3_kvartal_2026_goda_field_field': { + color_type: whiteColumn, + accessorKey: '3_kvartal_2026_goda_field_field', + }, + 'data.q3.adj_current': { + color_type: yellowColumn, + accessorKey: 'data.q3.adj_current', + }, + 'data.q3.adj_ssp': { + color_type: yellowColumn, + accessorKey: 'data.q3.adj_ssp', + }, + 'data.q3.adj_reserve': { + color_type: yellowColumn, + accessorKey: 'data.q3.adj_reserve', + }, + 'data.q3.adj_comment': { + color_type: yellowColumn, + accessorKey: 'data.q3.adj_comment', + }, + 'data.q3.corrected_plan': { + color_type: yellowColumn, + accessorKey: 'data.q3.corrected_plan', + }, + 'data.q3.pay_date': { + color_type: blueColumn, + accessorKey: 'data.q3.pay_date', + }, + 'data.q3.pay_amount': { + color_type: blueColumn, + accessorKey: 'data.q3.pay_amount', + }, + 'data.q3.pay_comment': { + color_type: blueColumn, + accessorKey: 'data.q3.pay_comment', + }, + 'data.q3.pay_act': { + color_type: blueColumn, + accessorKey: 'data.q3.pay_act', + }, + 'data.q3.booking': { + color_type: orangeColumn, + accessorKey: 'data.q3.booking', + }, + 'data.q3.actual_m1': { + color_type: greenColumn, + accessorKey: 'data.q3.actual_m1', + }, + 'data.q3.actual_m2': { + color_type: greenColumn, + accessorKey: 'data.q3.actual_m2', + }, + 'data.q3.actual_m3': { + color_type: greenColumn, + accessorKey: 'data.q3.actual_m3', + }, + 'data.q3.actual_quarter': { + color_type: greenColumn, + accessorKey: 'data.q3.actual_quarter', + }, + 'data.q3.residual_after_booking': { + color_type: orangeColumn, + accessorKey: 'data.q3.residual_after_booking', + }, + 'data.q3.residual_after_actual': { + color_type: greenColumn, + accessorKey: 'data.q3.residual_after_actual', + }, + 'data.q3.transfer_q4': { + color_type: redColumn, + accessorKey: 'data.q3.transfer_q4', + }, + 'data.q3.transfer_q4_delay_acts': { + color_type: redColumn, + accessorKey: 'data.q3.transfer_q4_delay_acts', + }, + 'data.q3.transfer_q4_delay_procurement': { + color_type: redColumn, + accessorKey: 'data.q3.transfer_q4_delay_procurement', + }, + 'data.q3.transfer_q4_economy_rf': { + color_type: redColumn, + accessorKey: 'data.q3.transfer_q4_economy_rf', + }, + 'data.q3.transfer_next_comment': { + color_type: redColumn, + accessorKey: 'data.q3.transfer_next_comment', + }, + 'data.q3.transfer_econ': { + color_type: redColumn, + accessorKey: 'data.q3.transfer_econ', + }, + 'data.q3.total': { + color_type: redColumn, + accessorKey: 'data.q3.total', + }, + 'data.q4.target_change': { + color_type: redColumn, + accessorKey: 'data.q4.target_change', + }, + 'data.q4.base_correction': { + color_type: redColumn, + accessorKey: 'data.q4.base_correction', + }, + 'data.q4.base_correction_comment': { + color_type: redColumn, + accessorKey: 'data.q4.base_correction_comment', + }, + 'data.q4.revision_inc': { + color_type: yellowColumn, + accessorKey: 'data.q4.revision_inc', + }, + 'data.q4.revision_seq': { + color_type: yellowColumn, + accessorKey: 'data.q4.revision_seq', + }, + 'data.q4.revision_comment': { + color_type: yellowColumn, + accessorKey: 'data.q4.revision_comment', + }, + 'data.q4.new_plan': { + color_type: yellowColumn, + accessorKey: 'data.q4.new_plan', + }, + '4_kvartal_2026_goda_field_field': { + color_type: whiteColumn, + accessorKey: '4_kvartal_2026_goda_field_field', + }, + 'data.q4.adj_current': { + color_type: yellowColumn, + accessorKey: 'data.q4.adj_current', + }, + 'data.q4.adj_ssp': { + color_type: yellowColumn, + accessorKey: 'data.q4.adj_ssp', + }, + 'data.q4.adj_reserve': { + color_type: yellowColumn, + accessorKey: 'data.q4.adj_reserve', + }, + 'data.q4.adj_comment': { + color_type: yellowColumn, + accessorKey: 'data.q4.adj_comment', + }, + 'data.q4.corrected_plan': { + color_type: yellowColumn, + accessorKey: 'data.q4.corrected_plan', + }, + 'data.q4.pay_date': { + color_type: blueColumn, + accessorKey: 'data.q4.pay_date', + }, + 'data.q4.pay_amount': { + color_type: blueColumn, + accessorKey: 'data.q4.pay_amount', + }, + 'data.q4.pay_comment': { + color_type: blueColumn, + accessorKey: 'data.q4.pay_comment', + }, + 'data.q4.pay_act': { + color_type: blueColumn, + accessorKey: 'data.q4.pay_act', + }, + 'data.q4.booking': { + color_type: orangeColumn, + accessorKey: 'data.q4.booking', + }, + 'data.q4.actual_m1': { + color_type: greenColumn, + accessorKey: 'data.q4.actual_m1', + }, + 'data.q4.actual_m2': { + color_type: greenColumn, + accessorKey: 'data.q4.actual_m2', + }, + 'data.q4.actual_m3': { + color_type: greenColumn, + accessorKey: 'data.q4.actual_m3', + }, + 'data.q4.actual_spod': { + color_type: greenColumn, + accessorKey: 'data.q4.actual_spod', + }, + 'data.q4.actual_quarter': { + color_type: greenColumn, + accessorKey: 'data.q4.actual_quarter', + }, + 'data.q4.residual_after_booking': { + color_type: orangeColumn, + accessorKey: 'data.q4.residual_after_booking', + }, + 'data.q4.residual_after_actual': { + color_type: greenColumn, + accessorKey: 'data.q4.residual_after_actual', + }, + 'data.q4.transfer_econ': { + color_type: redColumn, + accessorKey: 'data.q4.transfer_econ', + }, + 'data.totals.fact_year': { + color_type: greenColumn, + accessorKey: 'data.totals.fact_year', + }, + '2026_god_field_field_5': { + color_type: whiteColumn, + accessorKey: '2026_god_field_field_5', + }, + 'data.totals.pay_year': { + color_type: blueColumn, + accessorKey: 'data.totals.pay_year', + }, + }, + columns: [ + { + header: ' ', + accessorKey: 'field', + columns: [ + { + header: ' ', + accessorKey: 'field_field', + columns: [ + { + header: 'Код раздела', + accessorKey: 'data.header.section_code', + columnLetter: 'A', + size: 150, + filterFn: 'contains', + }, + { + header: 'ID статьи', + accessorKey: 'data.header.item_id', + columnLetter: 'B', + size: 150, + filterFn: 'contains', + }, + { + header: 'ID группы номенклатуры', + accessorKey: 'data.header.num_group', + columnLetter: 'C', + size: 220, + filterFn: 'contains', + }, + { + header: 'Наименование', + accessorKey: 'data.header.name', + columnLetter: 'D', + size: 150, + filterFn: 'contains', + }, + { + header: 'ВСП РФ', + accessorKey: 'data.header.vsp_id', + columnLetter: 'E', + size: 150, + filterFn: 'contains', + editType: 'vsp_dropdown', + }, + { + header: 'Адрес ВСП', + accessorKey: 'data.header.vsp_address', + columnLetter: 'E1', + size: 220, + filterFn: 'contains', + }, + ], + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + ], + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + { + header: '2026 год', + accessorKey: '2026_god', + columns: [ + { + header: 'Планирование годовых показателей', + accessorKey: '2026_god_planirovanie_godovykh_pokazateley', + columns: [ + { + header: '1 квартал', + accessorKey: 'data.plan.q1', + columnLetter: 'F', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + { + header: '2 квартал', + accessorKey: 'data.plan.q2', + columnLetter: 'G', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + { + header: '3 квартал', + accessorKey: 'data.plan.q3', + columnLetter: 'H', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + { + header: '4 квартал', + accessorKey: 'data.plan.q4', + columnLetter: 'I', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + { + header: 'Год', + accessorKey: 'data.plan.year', + columnLetter: 'J', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + { + header: 'Комментарий', + accessorKey: 'data.plan.comment', + columnLetter: 'K', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + ], + muiTableHeadCellProps: { + sx: { + backgroundColor: '#B2A1C7', + color: '#000000', + }, + }, + }, - { - header: "Секвестирование ДФиП", - accessorKey: "2026_god_sekvestirovanie_dfip", - columns: [ - { - header: "1 квартал", - accessorKey: "data.seq_dfip.q1", - columnLetter: "M", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - { - header: "2 квартал", - accessorKey: "data.seq_dfip.q2", - columnLetter: "N", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - { - header: "3 квартал", - accessorKey: "data.seq_dfip.q3", - columnLetter: "O", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - { - header: "4 квартал", - accessorKey: "data.seq_dfip.q4", - columnLetter: "P", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - { - header: "Год", - accessorKey: "data.seq_dfip.year", - columnLetter: "Q", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - { - header: "Обоснование", - accessorKey: "data.seq_dfip.justification", - columnLetter: "R", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - ], - muiTableHeadCellProps: { - sx: { - backgroundColor: "#B2A1C7", - color: "#000000", - }, - }, - }, - { - header: "Секвестирование ССП ГО", - accessorKey: "2026_god_sekvestirovanie_ssp_go", - columns: [ - { - header: "1 квартал", - accessorKey: "data.seq_ssp.q1", - columnLetter: "T", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - { - header: "2 квартал", - accessorKey: "data.seq_ssp.q2", - columnLetter: "U", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - { - header: "3 квартал", - accessorKey: "data.seq_ssp.q3", - columnLetter: "V", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - { - header: "4 квартал", - accessorKey: "data.seq_ssp.q4", - columnLetter: "W", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - { - header: "Год", - accessorKey: "data.seq_ssp.year", - columnLetter: "X", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - { - header: "Обоснование", - accessorKey: "data.seq_ssp.justification", - columnLetter: "Y", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - ], - muiTableHeadCellProps: { - sx: { - backgroundColor: "#B2A1C7", - color: "#000000", - }, - }, - }, - { - header: "Утвержденная смета расходов", - accessorKey: "2026_god_utverzhdennaya_smeta_raskhodov", - columns: [ - { - header: "1 квартал", - accessorKey: "data.approved.q1", - columnLetter: "AA", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - { - header: "2 квартал", - accessorKey: "data.approved.q2", - columnLetter: "AB", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - { - header: "3 квартал", - accessorKey: "data.approved.q3", - columnLetter: "AC", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - { - header: "4 квартал", - accessorKey: "data.approved.q4", - columnLetter: "AD", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - { - header: "Год", - accessorKey: "data.approved.year", - columnLetter: "AE", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - ], - muiTableHeadCellProps: { - sx: { - backgroundColor: "#B2A1C7", - color: "#000000", - }, - }, - }, - { - header: "Параметры заключенного хозяйственного договора", - accessorKey: - "2026_god_parametry_zaklyuchennogo_khozyaystvennogo_dogovora", - columns: [ - { - header: "Контрагент", - accessorKey: "data.contract.counterparty", - columnLetter: "AG", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - { - header: "Номер", - accessorKey: "data.contract.reference", - columnLetter: "AH", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - { - header: "Дата", - accessorKey: "data.contract.date", - columnLetter: "AI", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - { - header: "Предмет", - accessorKey: "data.contract.subject", - columnLetter: "AJ", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - { - header: "Валюта", - accessorKey: "data.contract.currency", - columnLetter: "AK", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - { - header: "Предельная стоимость", - accessorKey: "data.contract.ceiling", - columnLetter: "AL", - size: 200, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - { - header: "Ставка НДС (%)", - accessorKey: "data.contract.vat_rate", - columnLetter: "AM", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - { - header: "Срок", - accessorKey: "data.contract.deadline", - columnLetter: "AN", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - { - header: "Схема платежа", - accessorKey: "data.contract.scheme", - columnLetter: "AO", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - { - header: "АКТ", - accessorKey: "data.contract.act", - columnLetter: "AP", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - { - header: "Комментарий", - accessorKey: "data.contract.comment", - columnLetter: "AQ", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - { - header: "Бронь средств в 1 квартале", - accessorKey: "data.booking.y2026.q1", - columnLetter: "AR", - size: 260, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FABF8F", - color: "#000000", - }, - }, - }, - { - header: "Бронь средств во 2 квартале", - accessorKey: "data.booking.y2026.q2", - columnLetter: "AS", - size: 270, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FABF8F", - color: "#000000", - }, - }, - }, - { - header: "Бронь средств в 3 квартале", - accessorKey: "data.booking.y2026.q3", - columnLetter: "AT", - size: 260, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FABF8F", - color: "#000000", - }, - }, - }, - { - header: "Бронь средств в 4 квартале", - accessorKey: "data.booking.y2026.q4", - columnLetter: "AU", - size: 260, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FABF8F", - color: "#000000", - }, - }, - }, - ], - muiTableHeadCellProps: { - sx: { - backgroundColor: "#B2A1C7", - color: "#000000", - }, - }, - }, - ], - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - { - header: "2027 год", - accessorKey: "2027_god", - columns: [ - { - header: "", - accessorKey: "2027_god_field", - columns: [ - { - header: "Бронь средств в 1 квартале", - accessorKey: "data.booking.y2027.q1", - columnLetter: "AV", - size: 260, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FABF8F", - color: "#000000", - }, - }, - }, - { - header: "Бронь средств во 2 квартале", - accessorKey: "data.booking.y2027.q2", - columnLetter: "AW", - size: 270, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FABF8F", - color: "#000000", - }, - }, - }, - { - header: "Бронь средств в 3 квартале", - accessorKey: "data.booking.y2027.q3", - columnLetter: "AX", - size: 260, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FABF8F", - color: "#000000", - }, - }, - }, - { - header: "Бронь средств в 4 квартале", - accessorKey: "data.booking.y2027.q4", - columnLetter: "AY", - size: 260, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FABF8F", - color: "#000000", - }, - }, - }, - ], - muiTableHeadCellProps: { - sx: { - backgroundColor: "#B2A1C7", - color: "#000000", - }, - }, - }, - ], - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - { - header: "1 квартал 2026 года", - accessorKey: "1_kvartal_2026_goda", - columns: [ - { - header: "Корректировки плановых значений", - accessorKey: - "1_kvartal_2026_goda_korrektirovki_planovykh_znacheniy", - columns: [ - { - header: "Текущие (= 0)", - accessorKey: "data.q1.adj_current", - columnLetter: "BA", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFF66", - color: "#000000", - }, - }, - }, - { - header: "Корректиз сметы ГО", - accessorKey: "data.q1.adj_ssp", - columnLetter: "BB", - size: 190, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFF66", - color: "#000000", - }, - }, - }, - { - header: "Корректиз резерва", - accessorKey: "data.q1.adj_reserve", - columnLetter: "BC", - size: 180, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFF66", - color: "#000000", - }, - }, - }, - { - header: "Комментарий", - accessorKey: "data.q1.adj_comment", - columnLetter: "BD", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFF66", - color: "#000000", - }, - }, - }, - { - header: "Базовый план с учетом корректировок", - accessorKey: "data.q1.corrected_plan", - columnLetter: "BE", - size: 350, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFF66", - color: "#000000", - }, - }, - }, - ], - muiTableHeadCellProps: { - sx: { - backgroundColor: "#B2A1C7", - color: "#000000", - }, - }, - }, + { + header: 'Секвестирование ДФиП', + accessorKey: '2026_god_sekvestirovanie_dfip', + columns: [ + { + header: '1 квартал', + accessorKey: 'data.seq_dfip.q1', + columnLetter: 'M', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + { + header: '2 квартал', + accessorKey: 'data.seq_dfip.q2', + columnLetter: 'N', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + { + header: '3 квартал', + accessorKey: 'data.seq_dfip.q3', + columnLetter: 'O', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + { + header: '4 квартал', + accessorKey: 'data.seq_dfip.q4', + columnLetter: 'P', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + { + header: 'Год', + accessorKey: 'data.seq_dfip.year', + columnLetter: 'Q', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + { + header: 'Обоснование', + accessorKey: 'data.seq_dfip.justification', + columnLetter: 'R', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + ], + muiTableHeadCellProps: { + sx: { + backgroundColor: '#B2A1C7', + color: '#000000', + }, + }, + }, + { + header: 'Секвестирование ССП ГО', + accessorKey: '2026_god_sekvestirovanie_ssp_go', + columns: [ + { + header: '1 квартал', + accessorKey: 'data.seq_ssp.q1', + columnLetter: 'T', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + { + header: '2 квартал', + accessorKey: 'data.seq_ssp.q2', + columnLetter: 'U', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + { + header: '3 квартал', + accessorKey: 'data.seq_ssp.q3', + columnLetter: 'V', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + { + header: '4 квартал', + accessorKey: 'data.seq_ssp.q4', + columnLetter: 'W', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + { + header: 'Год', + accessorKey: 'data.seq_ssp.year', + columnLetter: 'X', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + { + header: 'Обоснование', + accessorKey: 'data.seq_ssp.justification', + columnLetter: 'Y', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + ], + muiTableHeadCellProps: { + sx: { + backgroundColor: '#B2A1C7', + color: '#000000', + }, + }, + }, + { + header: 'Утвержденная смета расходов', + accessorKey: '2026_god_utverzhdennaya_smeta_raskhodov', + columns: [ + { + header: '1 квартал', + accessorKey: 'data.approved.q1', + columnLetter: 'AA', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + { + header: '2 квартал', + accessorKey: 'data.approved.q2', + columnLetter: 'AB', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + { + header: '3 квартал', + accessorKey: 'data.approved.q3', + columnLetter: 'AC', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + { + header: '4 квартал', + accessorKey: 'data.approved.q4', + columnLetter: 'AD', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + { + header: 'Год', + accessorKey: 'data.approved.year', + columnLetter: 'AE', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + ], + muiTableHeadCellProps: { + sx: { + backgroundColor: '#B2A1C7', + color: '#000000', + }, + }, + }, + { + header: 'Параметры заключенного хозяйственного договора', + accessorKey: '2026_god_parametry_zaklyuchennogo_khozyaystvennogo_dogovora', + columns: [ + { + header: 'Контрагент', + accessorKey: 'data.contract.counterparty', + columnLetter: 'AG', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + { + header: 'Номер', + accessorKey: 'data.contract.reference', + columnLetter: 'AH', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + { + header: 'Дата', + accessorKey: 'data.contract.date', + columnLetter: 'AI', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + { + header: 'Предмет', + accessorKey: 'data.contract.subject', + columnLetter: 'AJ', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + { + header: 'Валюта', + accessorKey: 'data.contract.currency', + columnLetter: 'AK', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + { + header: 'Предельная стоимость', + accessorKey: 'data.contract.ceiling', + columnLetter: 'AL', + size: 200, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + { + header: 'Ставка НДС (%)', + accessorKey: 'data.contract.vat_rate', + columnLetter: 'AM', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + { + header: 'Срок', + accessorKey: 'data.contract.deadline', + columnLetter: 'AN', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + { + header: 'Схема платежа', + accessorKey: 'data.contract.scheme', + columnLetter: 'AO', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + { + header: 'АКТ', + accessorKey: 'data.contract.act', + columnLetter: 'AP', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + { + header: 'Комментарий', + accessorKey: 'data.contract.comment', + columnLetter: 'AQ', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + { + header: 'Бронь средств в 1 квартале', + accessorKey: 'data.booking.y2026.q1', + columnLetter: 'AR', + size: 260, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FABF8F', + color: '#000000', + }, + }, + }, + { + header: 'Бронь средств во 2 квартале', + accessorKey: 'data.booking.y2026.q2', + columnLetter: 'AS', + size: 270, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FABF8F', + color: '#000000', + }, + }, + }, + { + header: 'Бронь средств в 3 квартале', + accessorKey: 'data.booking.y2026.q3', + columnLetter: 'AT', + size: 260, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FABF8F', + color: '#000000', + }, + }, + }, + { + header: 'Бронь средств в 4 квартале', + accessorKey: 'data.booking.y2026.q4', + columnLetter: 'AU', + size: 260, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FABF8F', + color: '#000000', + }, + }, + }, + ], + muiTableHeadCellProps: { + sx: { + backgroundColor: '#B2A1C7', + color: '#000000', + }, + }, + }, + ], + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + { + header: '2027 год', + accessorKey: '2027_god', + columns: [ + { + header: '', + accessorKey: '2027_god_field', + columns: [ + { + header: 'Бронь средств в 1 квартале', + accessorKey: 'data.booking.y2027.q1', + columnLetter: 'AV', + size: 260, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FABF8F', + color: '#000000', + }, + }, + }, + { + header: 'Бронь средств во 2 квартале', + accessorKey: 'data.booking.y2027.q2', + columnLetter: 'AW', + size: 270, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FABF8F', + color: '#000000', + }, + }, + }, + { + header: 'Бронь средств в 3 квартале', + accessorKey: 'data.booking.y2027.q3', + columnLetter: 'AX', + size: 260, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FABF8F', + color: '#000000', + }, + }, + }, + { + header: 'Бронь средств в 4 квартале', + accessorKey: 'data.booking.y2027.q4', + columnLetter: 'AY', + size: 260, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FABF8F', + color: '#000000', + }, + }, + }, + ], + muiTableHeadCellProps: { + sx: { + backgroundColor: '#B2A1C7', + color: '#000000', + }, + }, + }, + ], + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + { + header: '1 квартал 2026 года', + accessorKey: '1_kvartal_2026_goda', + columns: [ + { + header: 'Корректировки плановых значений', + accessorKey: '1_kvartal_2026_goda_korrektirovki_planovykh_znacheniy', + columns: [ + { + header: 'Текущие (= 0)', + accessorKey: 'data.q1.adj_current', + columnLetter: 'BA', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFF66', + color: '#000000', + }, + }, + }, + { + header: 'Корректиз сметы ГО', + accessorKey: 'data.q1.adj_ssp', + columnLetter: 'BB', + size: 190, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFF66', + color: '#000000', + }, + }, + }, + { + header: 'Корректиз резерва', + accessorKey: 'data.q1.adj_reserve', + columnLetter: 'BC', + size: 180, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFF66', + color: '#000000', + }, + }, + }, + { + header: 'Комментарий', + accessorKey: 'data.q1.adj_comment', + columnLetter: 'BD', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFF66', + color: '#000000', + }, + }, + }, + { + header: 'Базовый план с учетом корректировок', + accessorKey: 'data.q1.corrected_plan', + columnLetter: 'BE', + size: 350, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFF66', + color: '#000000', + }, + }, + }, + ], + muiTableHeadCellProps: { + sx: { + backgroundColor: '#B2A1C7', + color: '#000000', + }, + }, + }, - { - header: "Согласование платежей", - accessorKey: "1_kvartal_2026_goda_soglasovanie_platezhey", - columns: [ - { - header: "Дата платежа", - accessorKey: "data.q1.pay_date", - columnLetter: "BG", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#95B3D7", - color: "#000000", - }, - }, - }, - { - header: "Сумма платежа", - accessorKey: "data.q1.pay_amount", - columnLetter: "BH", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#95B3D7", - color: "#000000", - }, - }, - }, - { - header: "Комментарий", - accessorKey: "data.q1.pay_comment", - columnLetter: "BI", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#95B3D7", - color: "#000000", - }, - }, - }, - { - header: "Предоставление акта", - accessorKey: "data.q1.pay_act", - columnLetter: "BJ", - size: 190, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#95B3D7", - color: "#000000", - }, - }, - }, - ], - muiTableHeadCellProps: { - sx: { - backgroundColor: "#B2A1C7", - color: "#000000", - }, - }, - }, - { - header: "Фактические расходы", - accessorKey: "1_kvartal_2026_goda_fakticheskie_raskhody", - columns: [ - { - header: "Бронь1 квартал", - accessorKey: "data.q1.booking", - columnLetter: "BL", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FABF8F", - color: "#000000", - }, - }, - }, - { - header: "ФактЯнварь", - accessorKey: "data.q1.actual_m1", - columnLetter: "BM", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#C2D69B", - color: "#000000", - }, - }, - }, - { - header: "ФактФевраль", - accessorKey: "data.q1.actual_m2", - columnLetter: "BN", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#C2D69B", - color: "#000000", - }, - }, - }, - { - header: "ФактМарт", - accessorKey: "data.q1.actual_m3", - columnLetter: "BO", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#C2D69B", - color: "#000000", - }, - }, - }, - { - header: "Факт1 квартал", - accessorKey: "data.q1.actual_quarter", - columnLetter: "BP", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#C2D69B", - color: "#000000", - }, - }, - }, - { - header: "Остаток после брони 1 квартала", - accessorKey: "data.q1.residual_after_booking", - columnLetter: "BQ", - size: 300, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FABF8F", - color: "#000000", - }, - }, - }, - { - header: "Остаток после факта 1 квартала", - accessorKey: "data.q1.residual_after_actual", - columnLetter: "BR", - size: 300, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#C2D69B", - color: "#000000", - }, - }, - }, - ], - muiTableHeadCellProps: { - sx: { - backgroundColor: "#B2A1C7", - color: "#000000", - }, - }, - }, - { - header: "Корректировка остатка в последующие кварталы", - accessorKey: - "1_kvartal_2026_goda_korrektirovka_ostatka_v_posleduyuschie_kvartaly", - columns: [ - { - header: "Перенос во 2 квартал", - accessorKey: "data.q1.transfer_q2", - columnLetter: "BT", - size: 200, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#903C39", - color: "#FFFFFF", - }, - }, - }, - { - header: "Задержка списания расходов / предоставления актов", - accessorKey: "data.q1.transfer_q2_delay_acts", - columnLetter: "BU", - size: 490, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#903C39", - color: "#FFFFFF", - }, - }, - }, - { - header: "Задержка закупочных процедур", - accessorKey: "data.q1.transfer_q2_delay_procurement", - columnLetter: "BV", - size: 280, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#903C39", - color: "#FFFFFF", - }, - }, - }, - { - header: "экономия (будет использована РФ)", - accessorKey: "data.q1.transfer_q2_economy_rf", - columnLetter: "BW", - size: 320, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#903C39", - color: "#FFFFFF", - }, - }, - }, - { - header: "Комментарий переноса во2 квартал", - accessorKey: "data.q1.transfer_next_comment", - columnLetter: "BX", - size: 330, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#903C39", - color: "#FFFFFF", - }, - }, - }, - { - header: "Перенос в 3 квартал", - accessorKey: "data.q1.transfer_q3", - columnLetter: "BY", - size: 190, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#903C39", - color: "#FFFFFF", - }, - }, - }, - { - header: "Перенос в 4 квартал", - accessorKey: "data.q1.transfer_q4", - columnLetter: "BZ", - size: 190, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#903C39", - color: "#FFFFFF", - }, - }, - }, - { - header: "Комментарий переноса в3 и 4 квартал", - accessorKey: "data.q1.transfer_far_comment", - columnLetter: "CA", - size: 360, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#903C39", - color: "#FFFFFF", - }, - }, - }, - { - header: "Перенос в фонд экономии", - accessorKey: "data.q1.transfer_econ", - columnLetter: "CB", - size: 230, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#903C39", - color: "#FFFFFF", - }, - }, - }, - { - header: "ВСЕГО", - accessorKey: "data.q1.total", - columnLetter: "CC", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#903C39", - color: "#FFFFFF", - }, - }, - }, - ], - muiTableHeadCellProps: { - sx: { - backgroundColor: "#B2A1C7", - color: "#000000", - }, - }, - }, - ], - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - { - header: "2 квартал 2026 года", - accessorKey: "2_kvartal_2026_goda", - columns: [ - { - header: "Корректировка базового плана", - accessorKey: "2_kvartal_2026_goda_korrektirovka_bazovogo_plana", - columns: [ - { - header: - "Изменение целевого назначения перенесенной экономии (= 0)", - accessorKey: "data.q2.target_change", - columnLetter: "CE", - size: 250, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#903C39", - color: "#FFFFFF", - }, - }, - }, - { - header: "Корректировка статей базового плана (= 0)", - accessorKey: "data.q2.base_correction", - columnLetter: "CF", - size: 410, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#903C39", - color: "#FFFFFF", - }, - }, - }, - { - header: "Комментарий изменения базового плана", - accessorKey: "data.q2.base_correction_comment", - columnLetter: "CG", - size: 360, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#903C39", - color: "#FFFFFF", - }, - }, - }, - { - header: "ДФиПУвеличение плана (> 0)", - accessorKey: "data.q2.revision_inc", - columnLetter: "CH", - size: 270, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFF66", - color: "#000000", - }, - }, - }, - { - header: "ДФиПCеквестр плана (< 0)", - accessorKey: "data.q2.revision_seq", - columnLetter: "CI", - size: 250, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFF66", - color: "#000000", - }, - }, - }, - { - header: "Комментарий", - accessorKey: "data.q2.revision_comment", - columnLetter: "CJ", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFF66", - color: "#000000", - }, - }, - }, - { - header: "Скорректированный план на подпись", - accessorKey: "data.q2.new_plan", - columnLetter: "CK", - size: 330, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFF66", - color: "#000000", - }, - }, - }, - ], - muiTableHeadCellProps: { - sx: { - backgroundColor: "#B2A1C7", - color: "#000000", - }, - }, - }, + { + header: 'Согласование платежей', + accessorKey: '1_kvartal_2026_goda_soglasovanie_platezhey', + columns: [ + { + header: 'Дата платежа', + accessorKey: 'data.q1.pay_date', + columnLetter: 'BG', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#95B3D7', + color: '#000000', + }, + }, + }, + { + header: 'Сумма платежа', + accessorKey: 'data.q1.pay_amount', + columnLetter: 'BH', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#95B3D7', + color: '#000000', + }, + }, + }, + { + header: 'Комментарий', + accessorKey: 'data.q1.pay_comment', + columnLetter: 'BI', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#95B3D7', + color: '#000000', + }, + }, + }, + { + header: 'Предоставление акта', + accessorKey: 'data.q1.pay_act', + columnLetter: 'BJ', + size: 190, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#95B3D7', + color: '#000000', + }, + }, + }, + ], + muiTableHeadCellProps: { + sx: { + backgroundColor: '#B2A1C7', + color: '#000000', + }, + }, + }, + { + header: 'Фактические расходы', + accessorKey: '1_kvartal_2026_goda_fakticheskie_raskhody', + columns: [ + { + header: 'Бронь1 квартал', + accessorKey: 'data.q1.booking', + columnLetter: 'BL', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FABF8F', + color: '#000000', + }, + }, + }, + { + header: 'ФактЯнварь', + accessorKey: 'data.q1.actual_m1', + columnLetter: 'BM', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#C2D69B', + color: '#000000', + }, + }, + }, + { + header: 'ФактФевраль', + accessorKey: 'data.q1.actual_m2', + columnLetter: 'BN', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#C2D69B', + color: '#000000', + }, + }, + }, + { + header: 'ФактМарт', + accessorKey: 'data.q1.actual_m3', + columnLetter: 'BO', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#C2D69B', + color: '#000000', + }, + }, + }, + { + header: 'Факт1 квартал', + accessorKey: 'data.q1.actual_quarter', + columnLetter: 'BP', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#C2D69B', + color: '#000000', + }, + }, + }, + { + header: 'Остаток после брони 1 квартала', + accessorKey: 'data.q1.residual_after_booking', + columnLetter: 'BQ', + size: 300, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FABF8F', + color: '#000000', + }, + }, + }, + { + header: 'Остаток после факта 1 квартала', + accessorKey: 'data.q1.residual_after_actual', + columnLetter: 'BR', + size: 300, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#C2D69B', + color: '#000000', + }, + }, + }, + ], + muiTableHeadCellProps: { + sx: { + backgroundColor: '#B2A1C7', + color: '#000000', + }, + }, + }, + { + header: 'Корректировка остатка в последующие кварталы', + accessorKey: '1_kvartal_2026_goda_korrektirovka_ostatka_v_posleduyuschie_kvartaly', + columns: [ + { + header: 'Перенос во 2 квартал', + accessorKey: 'data.q1.transfer_q2', + columnLetter: 'BT', + size: 200, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#903C39', + color: '#FFFFFF', + }, + }, + }, + { + header: 'Задержка списания расходов / предоставления актов', + accessorKey: 'data.q1.transfer_q2_delay_acts', + columnLetter: 'BU', + size: 490, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#903C39', + color: '#FFFFFF', + }, + }, + }, + { + header: 'Задержка закупочных процедур', + accessorKey: 'data.q1.transfer_q2_delay_procurement', + columnLetter: 'BV', + size: 280, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#903C39', + color: '#FFFFFF', + }, + }, + }, + { + header: 'экономия (будет использована РФ)', + accessorKey: 'data.q1.transfer_q2_economy_rf', + columnLetter: 'BW', + size: 320, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#903C39', + color: '#FFFFFF', + }, + }, + }, + { + header: 'Комментарий переноса во2 квартал', + accessorKey: 'data.q1.transfer_next_comment', + columnLetter: 'BX', + size: 330, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#903C39', + color: '#FFFFFF', + }, + }, + }, + { + header: 'Перенос в 3 квартал', + accessorKey: 'data.q1.transfer_q3', + columnLetter: 'BY', + size: 190, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#903C39', + color: '#FFFFFF', + }, + }, + }, + { + header: 'Перенос в 4 квартал', + accessorKey: 'data.q1.transfer_q4', + columnLetter: 'BZ', + size: 190, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#903C39', + color: '#FFFFFF', + }, + }, + }, + { + header: 'Комментарий переноса в3 и 4 квартал', + accessorKey: 'data.q1.transfer_far_comment', + columnLetter: 'CA', + size: 360, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#903C39', + color: '#FFFFFF', + }, + }, + }, + { + header: 'Перенос в фонд экономии', + accessorKey: 'data.q1.transfer_econ', + columnLetter: 'CB', + size: 230, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#903C39', + color: '#FFFFFF', + }, + }, + }, + { + header: 'ВСЕГО', + accessorKey: 'data.q1.total', + columnLetter: 'CC', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#903C39', + color: '#FFFFFF', + }, + }, + }, + ], + muiTableHeadCellProps: { + sx: { + backgroundColor: '#B2A1C7', + color: '#000000', + }, + }, + }, + ], + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + { + header: '2 квартал 2026 года', + accessorKey: '2_kvartal_2026_goda', + columns: [ + { + header: 'Корректировка базового плана', + accessorKey: '2_kvartal_2026_goda_korrektirovka_bazovogo_plana', + columns: [ + { + header: 'Изменение целевого назначения перенесенной экономии (= 0)', + accessorKey: 'data.q2.target_change', + columnLetter: 'CE', + size: 250, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#903C39', + color: '#FFFFFF', + }, + }, + }, + { + header: 'Корректировка статей базового плана (= 0)', + accessorKey: 'data.q2.base_correction', + columnLetter: 'CF', + size: 410, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#903C39', + color: '#FFFFFF', + }, + }, + }, + { + header: 'Комментарий изменения базового плана', + accessorKey: 'data.q2.base_correction_comment', + columnLetter: 'CG', + size: 360, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#903C39', + color: '#FFFFFF', + }, + }, + }, + { + header: 'ДФиПУвеличение плана (> 0)', + accessorKey: 'data.q2.revision_inc', + columnLetter: 'CH', + size: 270, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFF66', + color: '#000000', + }, + }, + }, + { + header: 'ДФиПCеквестр плана (< 0)', + accessorKey: 'data.q2.revision_seq', + columnLetter: 'CI', + size: 250, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFF66', + color: '#000000', + }, + }, + }, + { + header: 'Комментарий', + accessorKey: 'data.q2.revision_comment', + columnLetter: 'CJ', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFF66', + color: '#000000', + }, + }, + }, + { + header: 'Скорректированный план на подпись', + accessorKey: 'data.q2.new_plan', + columnLetter: 'CK', + size: 330, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFF66', + color: '#000000', + }, + }, + }, + ], + muiTableHeadCellProps: { + sx: { + backgroundColor: '#B2A1C7', + color: '#000000', + }, + }, + }, - { - header: "Корректировки плановых значений", - accessorKey: - "2_kvartal_2026_goda_korrektirovki_planovykh_znacheniy", - columns: [ - { - header: "Текущие (= 0)", - accessorKey: "data.q2.adj_current", - columnLetter: "CM", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFF66", - color: "#000000", - }, - }, - }, - { - header: "Корректиз сметы ГО", - accessorKey: "data.q2.adj_ssp", - columnLetter: "CN", - size: 190, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFF66", - color: "#000000", - }, - }, - }, - { - header: "Корректиз резерва", - accessorKey: "data.q2.adj_reserve", - columnLetter: "CO", - size: 180, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFF66", - color: "#000000", - }, - }, - }, - { - header: "Комментарий", - accessorKey: "data.q2.adj_comment", - columnLetter: "CP", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFF66", - color: "#000000", - }, - }, - }, - { - header: "Скорректированный план с учетом корректировок", - accessorKey: "data.q2.corrected_plan", - columnLetter: "CQ", - size: 450, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFF66", - color: "#000000", - }, - }, - }, - ], - muiTableHeadCellProps: { - sx: { - backgroundColor: "#B2A1C7", - color: "#000000", - }, - }, - }, - { - header: "Согласование платежей", - accessorKey: "2_kvartal_2026_goda_soglasovanie_platezhey", - columns: [ - { - header: "Дата платежа", - accessorKey: "data.q2.pay_date", - columnLetter: "CS", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#95B3D7", - color: "#000000", - }, - }, - }, - { - header: "Сумма платежа", - accessorKey: "data.q2.pay_amount", - columnLetter: "CT", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#95B3D7", - color: "#000000", - }, - }, - }, - { - header: "Комментарий", - accessorKey: "data.q2.pay_comment", - columnLetter: "CU", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#95B3D7", - color: "#000000", - }, - }, - }, - { - header: "Предоставление акта", - accessorKey: "data.q2.pay_act", - columnLetter: "CV", - size: 190, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#95B3D7", - color: "#000000", - }, - }, - }, - ], - muiTableHeadCellProps: { - sx: { - backgroundColor: "#B2A1C7", - color: "#000000", - }, - }, - }, - { - header: "Фактические расходы", - accessorKey: "2_kvartal_2026_goda_fakticheskie_raskhody", - columns: [ - { - header: "Бронь2 квартал", - accessorKey: "data.q2.booking", - columnLetter: "CX", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FABF8F", - color: "#000000", - }, - }, - }, - { - header: "ФактАпрель", - accessorKey: "data.q2.actual_m1", - columnLetter: "CY", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#C2D69B", - color: "#000000", - }, - }, - }, - { - header: "ФактМай", - accessorKey: "data.q2.actual_m2", - columnLetter: "CZ", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#C2D69B", - color: "#000000", - }, - }, - }, - { - header: "ФактИюнь", - accessorKey: "data.q2.actual_m3", - columnLetter: "DA", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#C2D69B", - color: "#000000", - }, - }, - }, - { - header: "Факт2 квартал", - accessorKey: "data.q2.actual_quarter", - columnLetter: "DB", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#C2D69B", - color: "#000000", - }, - }, - }, - { - header: "Остаток после брони 2 квартала", - accessorKey: "data.q2.residual_after_booking", - columnLetter: "DC", - size: 300, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FABF8F", - color: "#000000", - }, - }, - }, - { - header: "Остаток после факта 2 квартала", - accessorKey: "data.q2.residual_after_actual", - columnLetter: "DD", - size: 300, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#C2D69B", - color: "#000000", - }, - }, - }, - ], - muiTableHeadCellProps: { - sx: { - backgroundColor: "#B2A1C7", - color: "#000000", - }, - }, - }, - { - header: "Корректировка остатка в последующие кварталы", - accessorKey: - "2_kvartal_2026_goda_korrektirovka_ostatka_v_posleduyuschie_kvartaly", - columns: [ - { - header: "Перенос в 3 квартал", - accessorKey: "data.q2.transfer_q3", - columnLetter: "DF", - size: 190, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#903C39", - color: "#FFFFFF", - }, - }, - }, - { - header: "Задержка списания расходов / предоставления актов", - accessorKey: "data.q2.transfer_q3_delay_acts", - columnLetter: "DG", - size: 490, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#903C39", - color: "#FFFFFF", - }, - }, - }, - { - header: "Задержка закупочных процедур", - accessorKey: "data.q2.transfer_q3_delay_procurement", - columnLetter: "DH", - size: 280, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#903C39", - color: "#FFFFFF", - }, - }, - }, - { - header: "экономия (будет использована РФ)", - accessorKey: "data.q2.transfer_q3_economy_rf", - columnLetter: "DI", - size: 320, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#903C39", - color: "#FFFFFF", - }, - }, - }, - { - header: "Комментарий переноса в3 квартал", - accessorKey: "data.q2.transfer_next_comment", - columnLetter: "DJ", - size: 320, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#903C39", - color: "#FFFFFF", - }, - }, - }, - { - header: "Перенос в 4 квартал", - accessorKey: "data.q2.transfer_q4", - columnLetter: "DK", - size: 190, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#903C39", - color: "#FFFFFF", - }, - }, - }, - { - header: "Комментарий переноса в4 квартал", - accessorKey: "data.q2.transfer_far_comment", - columnLetter: "DL", - size: 320, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#903C39", - color: "#FFFFFF", - }, - }, - }, - { - header: "Перенос в фонд экономии", - accessorKey: "data.q2.transfer_econ", - columnLetter: "DM", - size: 230, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#903C39", - color: "#FFFFFF", - }, - }, - }, - { - header: "ВСЕГО", - accessorKey: "data.q2.total", - columnLetter: "DN", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#903C39", - color: "#FFFFFF", - }, - }, - }, - ], - muiTableHeadCellProps: { - sx: { - backgroundColor: "#B2A1C7", - color: "#000000", - }, - }, - }, - ], - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - { - header: "3 квартал 2026 года", - accessorKey: "3_kvartal_2026_goda", - columns: [ - { - header: "Корректировка базового плана", - accessorKey: "3_kvartal_2026_goda_korrektirovka_bazovogo_plana", - columns: [ - { - header: - "Изменение целевого назначения перенесенной экономии (= 0)", - accessorKey: "data.q3.target_change", - columnLetter: "DP", - size: 250, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#903C39", - color: "#FFFFFF", - }, - }, - }, - { - header: "Корректировка статей базового плана (= 0)", - accessorKey: "data.q3.base_correction", - columnLetter: "DQ", - size: 410, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#903C39", - color: "#FFFFFF", - }, - }, - }, - { - header: "Комментарий изменения базового плана", - accessorKey: "data.q3.base_correction_comment", - columnLetter: "DR", - size: 360, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#903C39", - color: "#FFFFFF", - }, - }, - }, - { - header: "ДФиПУвеличение плана (> 0)", - accessorKey: "data.q3.revision_inc", - columnLetter: "DS", - size: 270, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFF66", - color: "#000000", - }, - }, - }, - { - header: "ДФиПCеквестр плана (< 0)", - accessorKey: "data.q3.revision_seq", - columnLetter: "DT", - size: 250, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFF66", - color: "#000000", - }, - }, - }, - { - header: "Комментарий", - accessorKey: "data.q3.revision_comment", - columnLetter: "DU", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFF66", - color: "#000000", - }, - }, - }, - { - header: "Скорректированный план на подпись", - accessorKey: "data.q3.new_plan", - columnLetter: "DV", - size: 330, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFF66", - color: "#000000", - }, - }, - }, - ], - muiTableHeadCellProps: { - sx: { - backgroundColor: "#B2A1C7", - color: "#000000", - }, - }, - }, + { + header: 'Корректировки плановых значений', + accessorKey: '2_kvartal_2026_goda_korrektirovki_planovykh_znacheniy', + columns: [ + { + header: 'Текущие (= 0)', + accessorKey: 'data.q2.adj_current', + columnLetter: 'CM', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFF66', + color: '#000000', + }, + }, + }, + { + header: 'Корректиз сметы ГО', + accessorKey: 'data.q2.adj_ssp', + columnLetter: 'CN', + size: 190, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFF66', + color: '#000000', + }, + }, + }, + { + header: 'Корректиз резерва', + accessorKey: 'data.q2.adj_reserve', + columnLetter: 'CO', + size: 180, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFF66', + color: '#000000', + }, + }, + }, + { + header: 'Комментарий', + accessorKey: 'data.q2.adj_comment', + columnLetter: 'CP', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFF66', + color: '#000000', + }, + }, + }, + { + header: 'Скорректированный план с учетом корректировок', + accessorKey: 'data.q2.corrected_plan', + columnLetter: 'CQ', + size: 450, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFF66', + color: '#000000', + }, + }, + }, + ], + muiTableHeadCellProps: { + sx: { + backgroundColor: '#B2A1C7', + color: '#000000', + }, + }, + }, + { + header: 'Согласование платежей', + accessorKey: '2_kvartal_2026_goda_soglasovanie_platezhey', + columns: [ + { + header: 'Дата платежа', + accessorKey: 'data.q2.pay_date', + columnLetter: 'CS', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#95B3D7', + color: '#000000', + }, + }, + }, + { + header: 'Сумма платежа', + accessorKey: 'data.q2.pay_amount', + columnLetter: 'CT', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#95B3D7', + color: '#000000', + }, + }, + }, + { + header: 'Комментарий', + accessorKey: 'data.q2.pay_comment', + columnLetter: 'CU', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#95B3D7', + color: '#000000', + }, + }, + }, + { + header: 'Предоставление акта', + accessorKey: 'data.q2.pay_act', + columnLetter: 'CV', + size: 190, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#95B3D7', + color: '#000000', + }, + }, + }, + ], + muiTableHeadCellProps: { + sx: { + backgroundColor: '#B2A1C7', + color: '#000000', + }, + }, + }, + { + header: 'Фактические расходы', + accessorKey: '2_kvartal_2026_goda_fakticheskie_raskhody', + columns: [ + { + header: 'Бронь2 квартал', + accessorKey: 'data.q2.booking', + columnLetter: 'CX', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FABF8F', + color: '#000000', + }, + }, + }, + { + header: 'ФактАпрель', + accessorKey: 'data.q2.actual_m1', + columnLetter: 'CY', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#C2D69B', + color: '#000000', + }, + }, + }, + { + header: 'ФактМай', + accessorKey: 'data.q2.actual_m2', + columnLetter: 'CZ', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#C2D69B', + color: '#000000', + }, + }, + }, + { + header: 'ФактИюнь', + accessorKey: 'data.q2.actual_m3', + columnLetter: 'DA', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#C2D69B', + color: '#000000', + }, + }, + }, + { + header: 'Факт2 квартал', + accessorKey: 'data.q2.actual_quarter', + columnLetter: 'DB', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#C2D69B', + color: '#000000', + }, + }, + }, + { + header: 'Остаток после брони 2 квартала', + accessorKey: 'data.q2.residual_after_booking', + columnLetter: 'DC', + size: 300, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FABF8F', + color: '#000000', + }, + }, + }, + { + header: 'Остаток после факта 2 квартала', + accessorKey: 'data.q2.residual_after_actual', + columnLetter: 'DD', + size: 300, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#C2D69B', + color: '#000000', + }, + }, + }, + ], + muiTableHeadCellProps: { + sx: { + backgroundColor: '#B2A1C7', + color: '#000000', + }, + }, + }, + { + header: 'Корректировка остатка в последующие кварталы', + accessorKey: '2_kvartal_2026_goda_korrektirovka_ostatka_v_posleduyuschie_kvartaly', + columns: [ + { + header: 'Перенос в 3 квартал', + accessorKey: 'data.q2.transfer_q3', + columnLetter: 'DF', + size: 190, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#903C39', + color: '#FFFFFF', + }, + }, + }, + { + header: 'Задержка списания расходов / предоставления актов', + accessorKey: 'data.q2.transfer_q3_delay_acts', + columnLetter: 'DG', + size: 490, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#903C39', + color: '#FFFFFF', + }, + }, + }, + { + header: 'Задержка закупочных процедур', + accessorKey: 'data.q2.transfer_q3_delay_procurement', + columnLetter: 'DH', + size: 280, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#903C39', + color: '#FFFFFF', + }, + }, + }, + { + header: 'экономия (будет использована РФ)', + accessorKey: 'data.q2.transfer_q3_economy_rf', + columnLetter: 'DI', + size: 320, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#903C39', + color: '#FFFFFF', + }, + }, + }, + { + header: 'Комментарий переноса в3 квартал', + accessorKey: 'data.q2.transfer_next_comment', + columnLetter: 'DJ', + size: 320, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#903C39', + color: '#FFFFFF', + }, + }, + }, + { + header: 'Перенос в 4 квартал', + accessorKey: 'data.q2.transfer_q4', + columnLetter: 'DK', + size: 190, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#903C39', + color: '#FFFFFF', + }, + }, + }, + { + header: 'Комментарий переноса в4 квартал', + accessorKey: 'data.q2.transfer_far_comment', + columnLetter: 'DL', + size: 320, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#903C39', + color: '#FFFFFF', + }, + }, + }, + { + header: 'Перенос в фонд экономии', + accessorKey: 'data.q2.transfer_econ', + columnLetter: 'DM', + size: 230, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#903C39', + color: '#FFFFFF', + }, + }, + }, + { + header: 'ВСЕГО', + accessorKey: 'data.q2.total', + columnLetter: 'DN', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#903C39', + color: '#FFFFFF', + }, + }, + }, + ], + muiTableHeadCellProps: { + sx: { + backgroundColor: '#B2A1C7', + color: '#000000', + }, + }, + }, + ], + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + { + header: '3 квартал 2026 года', + accessorKey: '3_kvartal_2026_goda', + columns: [ + { + header: 'Корректировка базового плана', + accessorKey: '3_kvartal_2026_goda_korrektirovka_bazovogo_plana', + columns: [ + { + header: 'Изменение целевого назначения перенесенной экономии (= 0)', + accessorKey: 'data.q3.target_change', + columnLetter: 'DP', + size: 250, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#903C39', + color: '#FFFFFF', + }, + }, + }, + { + header: 'Корректировка статей базового плана (= 0)', + accessorKey: 'data.q3.base_correction', + columnLetter: 'DQ', + size: 410, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#903C39', + color: '#FFFFFF', + }, + }, + }, + { + header: 'Комментарий изменения базового плана', + accessorKey: 'data.q3.base_correction_comment', + columnLetter: 'DR', + size: 360, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#903C39', + color: '#FFFFFF', + }, + }, + }, + { + header: 'ДФиПУвеличение плана (> 0)', + accessorKey: 'data.q3.revision_inc', + columnLetter: 'DS', + size: 270, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFF66', + color: '#000000', + }, + }, + }, + { + header: 'ДФиПCеквестр плана (< 0)', + accessorKey: 'data.q3.revision_seq', + columnLetter: 'DT', + size: 250, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFF66', + color: '#000000', + }, + }, + }, + { + header: 'Комментарий', + accessorKey: 'data.q3.revision_comment', + columnLetter: 'DU', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFF66', + color: '#000000', + }, + }, + }, + { + header: 'Скорректированный план на подпись', + accessorKey: 'data.q3.new_plan', + columnLetter: 'DV', + size: 330, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFF66', + color: '#000000', + }, + }, + }, + ], + muiTableHeadCellProps: { + sx: { + backgroundColor: '#B2A1C7', + color: '#000000', + }, + }, + }, - { - header: "Корректировки плановых значений", - accessorKey: - "3_kvartal_2026_goda_korrektirovki_planovykh_znacheniy", - columns: [ - { - header: "Текущие (= 0)", - accessorKey: "data.q3.adj_current", - columnLetter: "DX", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFF66", - color: "#000000", - }, - }, - }, - { - header: "Корректиз сметы ГО", - accessorKey: "data.q3.adj_ssp", - columnLetter: "DY", - size: 190, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFF66", - color: "#000000", - }, - }, - }, - { - header: "Корректиз резерва", - accessorKey: "data.q3.adj_reserve", - columnLetter: "DZ", - size: 180, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFF66", - color: "#000000", - }, - }, - }, - { - header: "Комментарий", - accessorKey: "data.q3.adj_comment", - columnLetter: "EA", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFF66", - color: "#000000", - }, - }, - }, - { - header: "Скорректированный план с учетом корректировок", - accessorKey: "data.q3.corrected_plan", - columnLetter: "EB", - size: 450, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFF66", - color: "#000000", - }, - }, - }, - ], - muiTableHeadCellProps: { - sx: { - backgroundColor: "#B2A1C7", - color: "#000000", - }, - }, - }, - { - header: "Согласование платежей", - accessorKey: "3_kvartal_2026_goda_soglasovanie_platezhey", - columns: [ - { - header: "Дата платежа", - accessorKey: "data.q3.pay_date", - columnLetter: "ED", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#95B3D7", - color: "#000000", - }, - }, - }, - { - header: "Сумма платежа", - accessorKey: "data.q3.pay_amount", - columnLetter: "EE", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#95B3D7", - color: "#000000", - }, - }, - }, - { - header: "Комментарий", - accessorKey: "data.q3.pay_comment", - columnLetter: "EF", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#95B3D7", - color: "#000000", - }, - }, - }, - { - header: "Предоставление акта", - accessorKey: "data.q3.pay_act", - columnLetter: "EG", - size: 190, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#95B3D7", - color: "#000000", - }, - }, - }, - ], - muiTableHeadCellProps: { - sx: { - backgroundColor: "#B2A1C7", - color: "#000000", - }, - }, - }, - { - header: "Фактические расходы", - accessorKey: "3_kvartal_2026_goda_fakticheskie_raskhody", - columns: [ - { - header: "Бронь3 квартал", - accessorKey: "data.q3.booking", - columnLetter: "EI", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FABF8F", - color: "#000000", - }, - }, - }, - { - header: "ФактИюль", - accessorKey: "data.q3.actual_m1", - columnLetter: "EJ", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#C2D69B", - color: "#000000", - }, - }, - }, - { - header: "ФактАвгуст", - accessorKey: "data.q3.actual_m2", - columnLetter: "EK", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#C2D69B", - color: "#000000", - }, - }, - }, - { - header: "ФактСентябрь", - accessorKey: "data.q3.actual_m3", - columnLetter: "EL", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#C2D69B", - color: "#000000", - }, - }, - }, - { - header: "Факт3 квартал", - accessorKey: "data.q3.actual_quarter", - columnLetter: "EM", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#C2D69B", - color: "#000000", - }, - }, - }, - { - header: "Остаток после брони 3 квартала", - accessorKey: "data.q3.residual_after_booking", - columnLetter: "EN", - size: 300, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FABF8F", - color: "#000000", - }, - }, - }, - { - header: "Остаток после факта 3 квартала", - accessorKey: "data.q3.residual_after_actual", - columnLetter: "EO", - size: 300, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#C2D69B", - color: "#000000", - }, - }, - }, - ], - muiTableHeadCellProps: { - sx: { - backgroundColor: "#B2A1C7", - color: "#000000", - }, - }, - }, - { - header: "Корректировка остатка в последующий квартал", - accessorKey: - "3_kvartal_2026_goda_korrektirovka_ostatka_v_posleduyuschiy_kvartal", - columns: [ - { - header: "Перенос в 4 квартал", - accessorKey: "data.q3.transfer_q4", - columnLetter: "EQ", - size: 190, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#903C39", - color: "#FFFFFF", - }, - }, - }, - { - header: "Задержка списания расходов / предоставления актов", - accessorKey: "data.q3.transfer_q4_delay_acts", - columnLetter: "ER", - size: 490, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#903C39", - color: "#FFFFFF", - }, - }, - }, - { - header: "Задержка закупочных процедур", - accessorKey: "data.q3.transfer_q4_delay_procurement", - columnLetter: "ES", - size: 280, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#903C39", - color: "#FFFFFF", - }, - }, - }, - { - header: "экономия (будет использована РФ)", - accessorKey: "data.q3.transfer_q4_economy_rf", - columnLetter: "ET", - size: 320, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#903C39", - color: "#FFFFFF", - }, - }, - }, - { - header: "Комментарий переноса в4 квартал", - accessorKey: "data.q3.transfer_next_comment", - columnLetter: "EU", - size: 320, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#903C39", - color: "#FFFFFF", - }, - }, - }, - { - header: "Перенос в фонд экономии", - accessorKey: "data.q3.transfer_econ", - columnLetter: "EV", - size: 230, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#903C39", - color: "#FFFFFF", - }, - }, - }, - { - header: "ВСЕГО", - accessorKey: "data.q3.total", - columnLetter: "EW", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#903C39", - color: "#FFFFFF", - }, - }, - }, - ], - muiTableHeadCellProps: { - sx: { - backgroundColor: "#B2A1C7", - color: "#000000", - }, - }, - }, - ], - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - { - header: "4 квартал 2026 года", - accessorKey: "4_kvartal_2026_goda", - columns: [ - { - header: "Корректировка базового плана", - accessorKey: "4_kvartal_2026_goda_korrektirovka_bazovogo_plana", - columns: [ - { - header: - "Изменение целевого назначения перенесенной экономии (= 0)", - accessorKey: "data.q4.target_change", - columnLetter: "EY", - size: 250, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#903C39", - color: "#FFFFFF", - }, - }, - }, - { - header: "Корректировка статей базового плана (= 0)", - accessorKey: "data.q4.base_correction", - columnLetter: "EZ", - size: 410, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#903C39", - color: "#FFFFFF", - }, - }, - }, - { - header: "Комментарий изменения базового плана", - accessorKey: "data.q4.base_correction_comment", - columnLetter: "FA", - size: 360, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#903C39", - color: "#FFFFFF", - }, - }, - }, - { - header: "ДФиПУвеличение плана (> 0)", - accessorKey: "data.q4.revision_inc", - columnLetter: "FB", - size: 270, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFF66", - color: "#000000", - }, - }, - }, - { - header: "ДФиПCеквестр плана (< 0)", - accessorKey: "data.q4.revision_seq", - columnLetter: "FC", - size: 250, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFF66", - color: "#000000", - }, - }, - }, - { - header: "Комментарий", - accessorKey: "data.q4.revision_comment", - columnLetter: "FD", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFF66", - color: "#000000", - }, - }, - }, - { - header: "Скорректированный план на подпись", - accessorKey: "data.q4.new_plan", - columnLetter: "FE", - size: 330, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFF66", - color: "#000000", - }, - }, - }, - ], - muiTableHeadCellProps: { - sx: { - backgroundColor: "#B2A1C7", - color: "#000000", - }, - }, - }, + { + header: 'Корректировки плановых значений', + accessorKey: '3_kvartal_2026_goda_korrektirovki_planovykh_znacheniy', + columns: [ + { + header: 'Текущие (= 0)', + accessorKey: 'data.q3.adj_current', + columnLetter: 'DX', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFF66', + color: '#000000', + }, + }, + }, + { + header: 'Корректиз сметы ГО', + accessorKey: 'data.q3.adj_ssp', + columnLetter: 'DY', + size: 190, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFF66', + color: '#000000', + }, + }, + }, + { + header: 'Корректиз резерва', + accessorKey: 'data.q3.adj_reserve', + columnLetter: 'DZ', + size: 180, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFF66', + color: '#000000', + }, + }, + }, + { + header: 'Комментарий', + accessorKey: 'data.q3.adj_comment', + columnLetter: 'EA', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFF66', + color: '#000000', + }, + }, + }, + { + header: 'Скорректированный план с учетом корректировок', + accessorKey: 'data.q3.corrected_plan', + columnLetter: 'EB', + size: 450, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFF66', + color: '#000000', + }, + }, + }, + ], + muiTableHeadCellProps: { + sx: { + backgroundColor: '#B2A1C7', + color: '#000000', + }, + }, + }, + { + header: 'Согласование платежей', + accessorKey: '3_kvartal_2026_goda_soglasovanie_platezhey', + columns: [ + { + header: 'Дата платежа', + accessorKey: 'data.q3.pay_date', + columnLetter: 'ED', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#95B3D7', + color: '#000000', + }, + }, + }, + { + header: 'Сумма платежа', + accessorKey: 'data.q3.pay_amount', + columnLetter: 'EE', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#95B3D7', + color: '#000000', + }, + }, + }, + { + header: 'Комментарий', + accessorKey: 'data.q3.pay_comment', + columnLetter: 'EF', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#95B3D7', + color: '#000000', + }, + }, + }, + { + header: 'Предоставление акта', + accessorKey: 'data.q3.pay_act', + columnLetter: 'EG', + size: 190, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#95B3D7', + color: '#000000', + }, + }, + }, + ], + muiTableHeadCellProps: { + sx: { + backgroundColor: '#B2A1C7', + color: '#000000', + }, + }, + }, + { + header: 'Фактические расходы', + accessorKey: '3_kvartal_2026_goda_fakticheskie_raskhody', + columns: [ + { + header: 'Бронь3 квартал', + accessorKey: 'data.q3.booking', + columnLetter: 'EI', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FABF8F', + color: '#000000', + }, + }, + }, + { + header: 'ФактИюль', + accessorKey: 'data.q3.actual_m1', + columnLetter: 'EJ', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#C2D69B', + color: '#000000', + }, + }, + }, + { + header: 'ФактАвгуст', + accessorKey: 'data.q3.actual_m2', + columnLetter: 'EK', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#C2D69B', + color: '#000000', + }, + }, + }, + { + header: 'ФактСентябрь', + accessorKey: 'data.q3.actual_m3', + columnLetter: 'EL', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#C2D69B', + color: '#000000', + }, + }, + }, + { + header: 'Факт3 квартал', + accessorKey: 'data.q3.actual_quarter', + columnLetter: 'EM', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#C2D69B', + color: '#000000', + }, + }, + }, + { + header: 'Остаток после брони 3 квартала', + accessorKey: 'data.q3.residual_after_booking', + columnLetter: 'EN', + size: 300, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FABF8F', + color: '#000000', + }, + }, + }, + { + header: 'Остаток после факта 3 квартала', + accessorKey: 'data.q3.residual_after_actual', + columnLetter: 'EO', + size: 300, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#C2D69B', + color: '#000000', + }, + }, + }, + ], + muiTableHeadCellProps: { + sx: { + backgroundColor: '#B2A1C7', + color: '#000000', + }, + }, + }, + { + header: 'Корректировка остатка в последующий квартал', + accessorKey: '3_kvartal_2026_goda_korrektirovka_ostatka_v_posleduyuschiy_kvartal', + columns: [ + { + header: 'Перенос в 4 квартал', + accessorKey: 'data.q3.transfer_q4', + columnLetter: 'EQ', + size: 190, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#903C39', + color: '#FFFFFF', + }, + }, + }, + { + header: 'Задержка списания расходов / предоставления актов', + accessorKey: 'data.q3.transfer_q4_delay_acts', + columnLetter: 'ER', + size: 490, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#903C39', + color: '#FFFFFF', + }, + }, + }, + { + header: 'Задержка закупочных процедур', + accessorKey: 'data.q3.transfer_q4_delay_procurement', + columnLetter: 'ES', + size: 280, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#903C39', + color: '#FFFFFF', + }, + }, + }, + { + header: 'экономия (будет использована РФ)', + accessorKey: 'data.q3.transfer_q4_economy_rf', + columnLetter: 'ET', + size: 320, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#903C39', + color: '#FFFFFF', + }, + }, + }, + { + header: 'Комментарий переноса в4 квартал', + accessorKey: 'data.q3.transfer_next_comment', + columnLetter: 'EU', + size: 320, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#903C39', + color: '#FFFFFF', + }, + }, + }, + { + header: 'Перенос в фонд экономии', + accessorKey: 'data.q3.transfer_econ', + columnLetter: 'EV', + size: 230, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#903C39', + color: '#FFFFFF', + }, + }, + }, + { + header: 'ВСЕГО', + accessorKey: 'data.q3.total', + columnLetter: 'EW', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#903C39', + color: '#FFFFFF', + }, + }, + }, + ], + muiTableHeadCellProps: { + sx: { + backgroundColor: '#B2A1C7', + color: '#000000', + }, + }, + }, + ], + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + { + header: '4 квартал 2026 года', + accessorKey: '4_kvartal_2026_goda', + columns: [ + { + header: 'Корректировка базового плана', + accessorKey: '4_kvartal_2026_goda_korrektirovka_bazovogo_plana', + columns: [ + { + header: 'Изменение целевого назначения перенесенной экономии (= 0)', + accessorKey: 'data.q4.target_change', + columnLetter: 'EY', + size: 250, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#903C39', + color: '#FFFFFF', + }, + }, + }, + { + header: 'Корректировка статей базового плана (= 0)', + accessorKey: 'data.q4.base_correction', + columnLetter: 'EZ', + size: 410, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#903C39', + color: '#FFFFFF', + }, + }, + }, + { + header: 'Комментарий изменения базового плана', + accessorKey: 'data.q4.base_correction_comment', + columnLetter: 'FA', + size: 360, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#903C39', + color: '#FFFFFF', + }, + }, + }, + { + header: 'ДФиПУвеличение плана (> 0)', + accessorKey: 'data.q4.revision_inc', + columnLetter: 'FB', + size: 270, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFF66', + color: '#000000', + }, + }, + }, + { + header: 'ДФиПCеквестр плана (< 0)', + accessorKey: 'data.q4.revision_seq', + columnLetter: 'FC', + size: 250, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFF66', + color: '#000000', + }, + }, + }, + { + header: 'Комментарий', + accessorKey: 'data.q4.revision_comment', + columnLetter: 'FD', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFF66', + color: '#000000', + }, + }, + }, + { + header: 'Скорректированный план на подпись', + accessorKey: 'data.q4.new_plan', + columnLetter: 'FE', + size: 330, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFF66', + color: '#000000', + }, + }, + }, + ], + muiTableHeadCellProps: { + sx: { + backgroundColor: '#B2A1C7', + color: '#000000', + }, + }, + }, - { - header: "Корректировки плановых значений", - accessorKey: - "4_kvartal_2026_goda_korrektirovki_planovykh_znacheniy", - columns: [ - { - header: "Текущие (= 0)", - accessorKey: "data.q4.adj_current", - columnLetter: "FG", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFF66", - color: "#000000", - }, - }, - }, - { - header: "Корректиз сметы ГО", - accessorKey: "data.q4.adj_ssp", - columnLetter: "FH", - size: 190, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFF66", - color: "#000000", - }, - }, - }, - { - header: "Корректиз резерва", - accessorKey: "data.q4.adj_reserve", - columnLetter: "FI", - size: 180, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFF66", - color: "#000000", - }, - }, - }, - { - header: "Комментарий", - accessorKey: "data.q4.adj_comment", - columnLetter: "FJ", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFF66", - color: "#000000", - }, - }, - }, - { - header: "Скорректированный план с учетом корректировок", - accessorKey: "data.q4.corrected_plan", - columnLetter: "FK", - size: 450, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFF66", - color: "#000000", - }, - }, - }, - ], - muiTableHeadCellProps: { - sx: { - backgroundColor: "#B2A1C7", - color: "#000000", - }, - }, - }, - { - header: "Согласование платежей", - accessorKey: "4_kvartal_2026_goda_soglasovanie_platezhey", - columns: [ - { - header: "Дата платежа", - accessorKey: "data.q4.pay_date", - columnLetter: "FM", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#95B3D7", - color: "#000000", - }, - }, - }, - { - header: "Сумма платежа", - accessorKey: "data.q4.pay_amount", - columnLetter: "FN", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#95B3D7", - color: "#000000", - }, - }, - }, - { - header: "Комментарий", - accessorKey: "data.q4.pay_comment", - columnLetter: "FO", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#95B3D7", - color: "#000000", - }, - }, - }, - { - header: "Предоставление акта", - accessorKey: "data.q4.pay_act", - columnLetter: "FP", - size: 190, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#95B3D7", - color: "#000000", - }, - }, - }, - ], - muiTableHeadCellProps: { - sx: { - backgroundColor: "#B2A1C7", - color: "#000000", - }, - }, - }, - { - header: "Фактические расходы", - accessorKey: "4_kvartal_2026_goda_fakticheskie_raskhody", - columns: [ - { - header: "Бронь4 квартал", - accessorKey: "data.q4.booking", - columnLetter: "FR", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FABF8F", - color: "#000000", - }, - }, - }, - { - header: "ФактОктябрь", - accessorKey: "data.q4.actual_m1", - columnLetter: "FS", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#C2D69B", - color: "#000000", - }, - }, - }, - { - header: "ФактНоябрь", - accessorKey: "data.q4.actual_m2", - columnLetter: "FT", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#C2D69B", - color: "#000000", - }, - }, - }, - { - header: "ФактДекабрь", - accessorKey: "data.q4.actual_m3", - columnLetter: "FU", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#C2D69B", - color: "#000000", - }, - }, - }, - { - header: "СПОД (Январь)", - accessorKey: "data.q4.actual_spod", - columnLetter: "FV", - size: 150, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#C2D69B", - color: "#000000", - }, - }, - }, - { - header: "Факт4 квартал (с уч СПОД)", - accessorKey: "data.q4.actual_quarter", - columnLetter: "FW", - size: 260, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#C2D69B", - color: "#000000", - }, - }, - }, - { - header: "Остаток после брони 4 квартала (с уч СПОД)", - accessorKey: "data.q4.residual_after_booking", - columnLetter: "FX", - size: 420, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FABF8F", - color: "#000000", - }, - }, - }, - { - header: "Остаток после факта 4 квартала (с уч СПОД)", - accessorKey: "data.q4.residual_after_actual", - columnLetter: "FY", - size: 420, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#C2D69B", - color: "#000000", - }, - }, - }, - ], - muiTableHeadCellProps: { - sx: { - backgroundColor: "#B2A1C7", - color: "#000000", - }, - }, - }, - { - header: "Экономия", - accessorKey: "4_kvartal_2026_goda_ekonomiya", - columns: [ - { - header: "Перенос в фонд экономии", - accessorKey: "data.q4.transfer_econ", - columnLetter: "GA", - size: 230, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#903C39", - color: "#FFFFFF", - }, - }, - }, - ], - muiTableHeadCellProps: { - sx: { - backgroundColor: "#B2A1C7", - color: "#000000", - }, - }, - }, - ], - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - { - header: "2026 год.", - accessorKey: "2026_god_43", - columns: [ - { - header: "", - accessorKey: "2026_god_field_5", - columns: [ - { - header: "Сумма фактических расходов за год", - accessorKey: "data.totals.fact_year", - columnLetter: "GC", - size: 330, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#C2D69B", - color: "#000000", - }, - }, - }, - { - header: "Сумма оплаты за год", - accessorKey: "data.totals.pay_year", - columnLetter: "GE", - size: 190, - filterFn: "contains", - muiTableHeadCellProps: { - sx: { - backgroundColor: "#95B3D7", - color: "#000000", - }, - }, - }, - ], - muiTableHeadCellProps: { - sx: { - backgroundColor: "#B2A1C7", - color: "#000000", - }, - }, - }, - ], - muiTableHeadCellProps: { - sx: { - backgroundColor: "#FFFFFF", - color: "#000000", - }, - }, - }, - ], - }, + { + header: 'Корректировки плановых значений', + accessorKey: '4_kvartal_2026_goda_korrektirovki_planovykh_znacheniy', + columns: [ + { + header: 'Текущие (= 0)', + accessorKey: 'data.q4.adj_current', + columnLetter: 'FG', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFF66', + color: '#000000', + }, + }, + }, + { + header: 'Корректиз сметы ГО', + accessorKey: 'data.q4.adj_ssp', + columnLetter: 'FH', + size: 190, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFF66', + color: '#000000', + }, + }, + }, + { + header: 'Корректиз резерва', + accessorKey: 'data.q4.adj_reserve', + columnLetter: 'FI', + size: 180, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFF66', + color: '#000000', + }, + }, + }, + { + header: 'Комментарий', + accessorKey: 'data.q4.adj_comment', + columnLetter: 'FJ', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFF66', + color: '#000000', + }, + }, + }, + { + header: 'Скорректированный план с учетом корректировок', + accessorKey: 'data.q4.corrected_plan', + columnLetter: 'FK', + size: 450, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFF66', + color: '#000000', + }, + }, + }, + ], + muiTableHeadCellProps: { + sx: { + backgroundColor: '#B2A1C7', + color: '#000000', + }, + }, + }, + { + header: 'Согласование платежей', + accessorKey: '4_kvartal_2026_goda_soglasovanie_platezhey', + columns: [ + { + header: 'Дата платежа', + accessorKey: 'data.q4.pay_date', + columnLetter: 'FM', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#95B3D7', + color: '#000000', + }, + }, + }, + { + header: 'Сумма платежа', + accessorKey: 'data.q4.pay_amount', + columnLetter: 'FN', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#95B3D7', + color: '#000000', + }, + }, + }, + { + header: 'Комментарий', + accessorKey: 'data.q4.pay_comment', + columnLetter: 'FO', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#95B3D7', + color: '#000000', + }, + }, + }, + { + header: 'Предоставление акта', + accessorKey: 'data.q4.pay_act', + columnLetter: 'FP', + size: 190, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#95B3D7', + color: '#000000', + }, + }, + }, + ], + muiTableHeadCellProps: { + sx: { + backgroundColor: '#B2A1C7', + color: '#000000', + }, + }, + }, + { + header: 'Фактические расходы', + accessorKey: '4_kvartal_2026_goda_fakticheskie_raskhody', + columns: [ + { + header: 'Бронь4 квартал', + accessorKey: 'data.q4.booking', + columnLetter: 'FR', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FABF8F', + color: '#000000', + }, + }, + }, + { + header: 'ФактОктябрь', + accessorKey: 'data.q4.actual_m1', + columnLetter: 'FS', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#C2D69B', + color: '#000000', + }, + }, + }, + { + header: 'ФактНоябрь', + accessorKey: 'data.q4.actual_m2', + columnLetter: 'FT', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#C2D69B', + color: '#000000', + }, + }, + }, + { + header: 'ФактДекабрь', + accessorKey: 'data.q4.actual_m3', + columnLetter: 'FU', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#C2D69B', + color: '#000000', + }, + }, + }, + { + header: 'СПОД (Январь)', + accessorKey: 'data.q4.actual_spod', + columnLetter: 'FV', + size: 150, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#C2D69B', + color: '#000000', + }, + }, + }, + { + header: 'Факт4 квартал (с уч СПОД)', + accessorKey: 'data.q4.actual_quarter', + columnLetter: 'FW', + size: 260, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#C2D69B', + color: '#000000', + }, + }, + }, + { + header: 'Остаток после брони 4 квартала (с уч СПОД)', + accessorKey: 'data.q4.residual_after_booking', + columnLetter: 'FX', + size: 420, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FABF8F', + color: '#000000', + }, + }, + }, + { + header: 'Остаток после факта 4 квартала (с уч СПОД)', + accessorKey: 'data.q4.residual_after_actual', + columnLetter: 'FY', + size: 420, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#C2D69B', + color: '#000000', + }, + }, + }, + ], + muiTableHeadCellProps: { + sx: { + backgroundColor: '#B2A1C7', + color: '#000000', + }, + }, + }, + { + header: 'Экономия', + accessorKey: '4_kvartal_2026_goda_ekonomiya', + columns: [ + { + header: 'Перенос в фонд экономии', + accessorKey: 'data.q4.transfer_econ', + columnLetter: 'GA', + size: 230, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#903C39', + color: '#FFFFFF', + }, + }, + }, + ], + muiTableHeadCellProps: { + sx: { + backgroundColor: '#B2A1C7', + color: '#000000', + }, + }, + }, + ], + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + { + header: '2026 год.', + accessorKey: '2026_god_43', + columns: [ + { + header: '', + accessorKey: '2026_god_field_5', + columns: [ + { + header: 'Сумма фактических расходов за год', + accessorKey: 'data.totals.fact_year', + columnLetter: 'GC', + size: 330, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#C2D69B', + color: '#000000', + }, + }, + }, + { + header: 'Сумма оплаты за год', + accessorKey: 'data.totals.pay_year', + columnLetter: 'GE', + size: 190, + filterFn: 'contains', + muiTableHeadCellProps: { + sx: { + backgroundColor: '#95B3D7', + color: '#000000', + }, + }, + }, + ], + muiTableHeadCellProps: { + sx: { + backgroundColor: '#B2A1C7', + color: '#000000', + }, + }, + }, + ], + muiTableHeadCellProps: { + sx: { + backgroundColor: '#FFFFFF', + color: '#000000', + }, + }, + }, + ], + }, }; diff --git a/web/src/components/RealtimeTable/constants/FORM_2/CAP.js b/web/src/components/RealtimeTable/constants/FORM_2/CAP.js index 0eaffdc..cadf2cd 100644 --- a/web/src/components/RealtimeTable/constants/FORM_2/CAP.js +++ b/web/src/components/RealtimeTable/constants/FORM_2/CAP.js @@ -25,6 +25,14 @@ export const config = { color_type: orangeColumn, accessorKey: "data.header.name", }, + "data.header.vsp_id": { + color_type: orangeColumn, + accessorKey: "data.header.vsp_id", + }, + "data.header.vsp_address": { + color_type: orangeColumn, + accessorKey: "data.header.vsp_address", + }, "data.header.internal_order": { color_type: orangeColumn, accessorKey: "data.header.internal_order", @@ -830,6 +838,33 @@ export const config = { }, ], }, + { + header: "ВСП РФ", + accessorKey: "field_vsp_rf", + columns: [ + { + header: "", + accessorKey: "data.header.vsp_id", + columnLetter: "G", + size: 150, + filterFn: "contains", + editType: "vsp_dropdown", + }, + ], + }, + { + header: "Адрес ВСП", + accessorKey: "field_adres_vsp", + columns: [ + { + header: "", + accessorKey: "data.header.vsp_address", + columnLetter: "G1", + size: 220, + filterFn: "contains", + }, + ], + }, { header: "Внутренний заказ", accessorKey: "field_vnutrenniy_zakaz", @@ -837,7 +872,7 @@ export const config = { { header: "", accessorKey: "data.header.internal_order", - columnLetter: "G", + columnLetter: "H", size: 150, filterFn: "contains", }, diff --git a/web/src/components/RealtimeTable/constants/FORM_2/OPER.js b/web/src/components/RealtimeTable/constants/FORM_2/OPER.js index 894bb85..bc7a9d4 100644 --- a/web/src/components/RealtimeTable/constants/FORM_2/OPER.js +++ b/web/src/components/RealtimeTable/constants/FORM_2/OPER.js @@ -25,6 +25,14 @@ export const config = { color_type: blueColumn, accessorKey: "data.header.name", }, + "data.header.vsp_id": { + color_type: blueColumn, + accessorKey: "data.header.vsp_id", + }, + "data.header.vsp_address": { + color_type: blueColumn, + accessorKey: "data.header.vsp_address", + }, "data.header.internal_order": { color_type: blueColumn, accessorKey: "data.header.internal_order", @@ -830,6 +838,33 @@ export const config = { }, ], }, + { + header: "ВСП РФ", + accessorKey: "field_vsp_rf", + columns: [ + { + header: "", + accessorKey: "data.header.vsp_id", + columnLetter: "G", + size: 150, + filterFn: "contains", + editType: "vsp_dropdown", + }, + ], + }, + { + header: "Адрес ВСП", + accessorKey: "field_adres_vsp", + columns: [ + { + header: "", + accessorKey: "data.header.vsp_address", + columnLetter: "G1", + size: 220, + filterFn: "contains", + }, + ], + }, { header: "Внутренний заказ", accessorKey: "field_vnutrenniy_zakaz", @@ -837,7 +872,7 @@ export const config = { { header: "", accessorKey: "data.header.internal_order", - columnLetter: "G", + columnLetter: "H", size: 150, filterFn: "contains", }, diff --git a/web/src/components/RealtimeTable/contexts/RealtimeContext.js b/web/src/components/RealtimeTable/contexts/RealtimeContext.js index 4028366..77d7305 100644 --- a/web/src/components/RealtimeTable/contexts/RealtimeContext.js +++ b/web/src/components/RealtimeTable/contexts/RealtimeContext.js @@ -1,454 +1,425 @@ -import React, { - createContext, - useContext, - useCallback, - useRef, - useState, - useEffect, -} from "react"; -import { useWebSocket } from "../hooks/useWebSocket"; -import { toast } from "react-toastify"; -import { getRowId } from "../utils/rowUtils"; +import { createContext, useCallback, useContext, useEffect, useRef, useState } from 'react'; +import { toast } from 'react-toastify'; +import { useWebSocket } from '../hooks/useWebSocket'; +import { getRowId } from '../utils/rowUtils'; const RealtimeContext = createContext(null); export const useRealtime = () => { - const context = useContext(RealtimeContext); - if (!context) { - throw new Error("useRealtime must be used within RealtimeProvider"); - } - return context; + const context = useContext(RealtimeContext); + if (!context) { + throw new Error('useRealtime must be used within RealtimeProvider'); + } + return context; }; -export const RealtimeProvider = ({ - children, - formId, - sheetName, - direction, - year, - userId, - isProject = false, -}) => { - // Формируем URL (кастомные секреты на фронте пока недоступны, делаем через REACT_APP_ROOT_PATH) - const wsUrl = - `${( - process.env.REACT_APP_API_URL || - process.env.REACT_APP_API_URL || - process.env.REACT_APP_ROOT_PATH || - "ws://localhost:8000" - ).replace(/^http/, "ws")}` + - (!isProject - ? `/api/v1/ws/form/${formId}/sheet/${sheetName}${direction ? `?direction=${direction}` : ""}` - : `/api/v1/ws/projects/${formId}/report/${year}/${sheetName}`); +export const RealtimeProvider = ({ children, formId, sheetName, direction, year, userId, isProject = false }) => { + // Формируем URL (кастомные секреты на фронте пока недоступны, делаем через REACT_APP_ROOT_PATH) + const wsUrl = `${( + process.env.REACT_APP_API_URL || process.env.REACT_APP_API_URL || process.env.REACT_APP_ROOT_PATH || 'ws://localhost:8000' + ).replace(/^http/, 'ws')}${ + !isProject + ? `/api/v1/ws/form/${formId}/sheet/${sheetName}${direction ? `?direction=${direction}` : ''}` + : `/api/v1/ws/projects/${formId}/report/${year}/${sheetName}` + }`; - //для ячеек которые редактируются другими пользователями - const [lockedCells, setLockedCells] = useState([]); - const handleMessage = useCallback((data) => { - // Обработка ошибок - if (data.error) { - console.log(data.error.message); - toast.error("Server error:" + data.error.message || ""); - onErrorRef.current?.(data.error); - return; - } + //для ячеек которые редактируются другими пользователями + const [lockedCells, setLockedCells] = useState([]); + const [vspOptions, setVspOptions] = useState([]); + const handleMessage = useCallback((data) => { + // Обработка ошибок + if (data.error) { + toast.error(`Server error:${data.error.message}` || ''); + onErrorRef.current?.(data.error); + return; + } - switch (data.event) { - case "cell_edit_start": - console.log("Cell edit started:", data); - if (onCellEditStartRef.current) { - onCellEditStartRef.current(data); - } - break; + switch (data.event) { + case 'cell_edit_start': + if (onCellEditStartRef.current) { + onCellEditStartRef.current(data); + } + break; - case "cell_edit_end": - console.log("Cell edit ended:", data); - if (onCellEditEndRef.current) { - onCellEditEndRef.current(data); - } - break; + case 'cell_edit_end': + if (onCellEditEndRef.current) { + onCellEditEndRef.current(data); + } + break; - case "cell_updated": - if (data.result && onCellUpdateRef.current) { - const updatedCells = Array.isArray(data.result) - ? data.result - : [data.result]; - onCellUpdateRef.current(updatedCells); - } - break; + case 'cell_updated': + if (data.result && onCellUpdateRef.current) { + const updatedCells = Array.isArray(data.result) ? data.result : [data.result]; + onCellUpdateRef.current(updatedCells); + } + break; - case "row_added": - if (data.result && onRowAddRef.current) { - onRowAddRef.current(data); - } - break; + case 'row_added': + if (data.result && onRowAddRef.current) { + onRowAddRef.current(data); + } + break; - case "row_deleted": - if (data.result && onRowDeleteRef.current) { - onRowDeleteRef.current(data); - } - break; + case 'row_deleted': + if (data.result && onRowDeleteRef.current) { + onRowDeleteRef.current(data); + } + break; - case "program_added": - console.log("Program added:", data); - if (data.result && onProgramAddRef.current) { - onProgramAddRef.current(data); - } - break; + case 'program_added': + if (data.result && onProgramAddRef.current) { + onProgramAddRef.current(data); + } + break; - case "project_added": - console.log("Project added:", data); - if (data.result && onProjectAddRef.current) { - onProjectAddRef.current(data); - } - break; + case 'project_added': + if (data.result && onProjectAddRef.current) { + onProjectAddRef.current(data); + } + break; - default: - console.log("Unknown event:", data.event); - } - }, []); + default: + } + }, []); - const { isConnectedRef, isConnected, sendMessage, disconnect, lastError } = - useWebSocket(wsUrl, handleMessage); + const { isConnectedRef, isConnected, sendMessage, disconnect, lastError } = useWebSocket(wsUrl, handleMessage); - const onCellUpdateRef = useRef(null); - const onRowAddRef = useRef(null); - const onRowDeleteRef = useRef(null); - const onProgramAddRef = useRef(null); - const onProjectAddRef = useRef(null); - const onErrorRef = useRef(null); - const onAuthSuccessRef = useRef(null); - const onCellEditStartRef = useRef(null); - const onCellEditEndRef = useRef(null); - const authAttemptedRef = useRef(false); - const reconnectTimerRef = useRef(null); + const onCellUpdateRef = useRef(null); + const onRowAddRef = useRef(null); + const onRowDeleteRef = useRef(null); + const onProgramAddRef = useRef(null); + const onProjectAddRef = useRef(null); + const onErrorRef = useRef(null); + const onAuthSuccessRef = useRef(null); + const onCellEditStartRef = useRef(null); + const onCellEditEndRef = useRef(null); + const authAttemptedRef = useRef(false); + const _reconnectTimerRef = useRef(null); - // Функция для получения токена из localStorage - const getAccessToken = useCallback(() => { - try { - const token = localStorage.getItem("access_token"); + // Функция для получения токена из localStorage + const getAccessToken = useCallback(() => { + try { + const token = localStorage.getItem('access_token'); - if (!token) { - console.warn("No access token found in localStorage"); - return null; - } + if (!token) { + return null; + } - return token; - } catch (error) { - console.error("Error reading token from localStorage:", error); - return null; - } - }, []); + return token; + } catch (_error) { + return null; + } + }, []); - const sendLogin = useCallback(() => { - const token = getAccessToken(); - if (!token) { - console.error("Cannot login: no token available"); - onErrorRef.current?.("Токен авторизации не найден"); - return false; - } + const sendLogin = useCallback(() => { + const token = getAccessToken(); + if (!token) { + onErrorRef.current?.('Токен авторизации не найден'); + return false; + } - const loginMessage = { - event: "user_login", - data: { token }, - }; + const loginMessage = { + event: 'user_login', + data: { token }, + }; - return sendMessage(loginMessage); - }, [getAccessToken, sendMessage]); + return sendMessage(loginMessage); + }, [getAccessToken, sendMessage]); - useEffect(() => { - if (isConnected && !authAttemptedRef.current) { - authAttemptedRef.current = true; - console.log("WebSocket connected, sending login..."); - setTimeout(() => { - sendLogin(); - }, 100); - } - }, [isConnected, sendLogin]); + useEffect(() => { + if (isConnected && !authAttemptedRef.current) { + authAttemptedRef.current = true; + setTimeout(() => { + sendLogin(); + }, 100); + } + }, [isConnected, sendLogin]); - useEffect(() => { - if (!isConnected) { - authAttemptedRef.current = false; - } - }, [isConnected]); + useEffect(() => { + if (!isConnected) { + authAttemptedRef.current = false; + } + }, [isConnected]); - const addCommonField = (message) => { - if (isProject) { - message.report_type = sheetName; - message.project_id = formId; - message.year = year; - } else { - message.sheet = sheetName; - message.form_id = formId; - message.direction = direction; - } - return message; - }; + const addCommonField = (message) => { + if (isProject) { + message.report_type = sheetName; + message.project_id = formId; + message.year = year; + } else { + message.sheet = sheetName; + message.form_id = formId; + message.direction = direction; + } + return message; + }; - // Функция для начала редактирования ячейки - const startEditing = useCallback( - async (row, column) => { - const columnId = column.id; - const rowId = row.id; + // Функция для начала редактирования ячейки + const startEditing = useCallback( + async (row, column) => { + const columnId = column.id; + const _rowId = row.id; - if (!isConnectedRef) { - onErrorRef.current?.("WebSocket не подключен"); - return false; - } + if (!isConnectedRef) { + onErrorRef.current?.('WebSocket не подключен'); + return false; + } - const lineId = row.id || null; - const colId = columnId.slice(5); // убираем префикс "data." + const lineId = row.id || null; + const colId = columnId.slice(5); // убираем префикс "data." - const message = { - event: "cell_edit_start", - data: { - line_id: lineId, - column: colId, - }, - }; + const message = { + event: 'cell_edit_start', + data: { + line_id: lineId, + column: colId, + }, + }; - const sent = sendMessage(message); - if (!sent) { - return false; - } + const sent = sendMessage(message); + if (!sent) { + return false; + } - return true; - }, - [isConnected, sendMessage], - ); + return true; + }, + [isConnected, sendMessage], + ); - // Функция для завершения редактирования ячейки - const endEditing = useCallback( - async (row, column) => { - const columnId = column.id; - const rowId = row.id; + // Функция для завершения редактирования ячейки + const endEditing = useCallback( + async (row, column) => { + const columnId = column.id; + const _rowId = row.id; - if (!isConnectedRef) { - onErrorRef.current?.("WebSocket не подключен"); - return false; - } + if (!isConnectedRef) { + onErrorRef.current?.('WebSocket не подключен'); + return false; + } - const lineId = row.id || null; - const colId = columnId.slice(5); + const lineId = row.id || null; + const colId = columnId.slice(5); - const message = { - event: "cell_edit_end", - data: { - line_id: lineId, - column: colId, - }, - }; + const message = { + event: 'cell_edit_end', + data: { + line_id: lineId, + column: colId, + }, + }; - const sent = sendMessage(message); - if (!sent) { - return false; - } + const sent = sendMessage(message); + if (!sent) { + return false; + } - return true; - }, - [isConnected, sendMessage], - ); + return true; + }, + [isConnected, sendMessage], + ); - const updateCell = useCallback( - async (row, column, value) => { - const columnId = column.id; - const rowId = row.id; - if (!isConnectedRef) { - onErrorRef.current?.("WebSocket не подключен"); - return false; - } + const updateCell = useCallback( + async (row, column, value) => { + const columnId = column.id; + const _rowId = row.id; + if (!isConnectedRef) { + onErrorRef.current?.('WebSocket не подключен'); + return false; + } - const lineId = getRowId(row); - const colId = columnId.slice(5); - const message = { - event: "cell_updated", - data: { - line_id: lineId, - line_id_code: row.id, - column: colId, - value: value, - }, - }; - const sent = sendMessage(message); + const lineId = getRowId(row); + const colId = columnId.slice(5); + const message = { + event: 'cell_updated', + data: { + line_id: lineId, + line_id_code: row.id, + column: colId, + value: value, + }, + }; + const sent = sendMessage(message); - if (!sent) { - return false; - } + if (!sent) { + return false; + } - return true; - }, - [isConnected, sendMessage], - ); + return true; + }, + [isConnected, sendMessage], + ); - const addRow = useCallback( - async (rowData) => { - if (!isConnectedRef) { - onErrorRef.current?.("Нет подключения или авторизации"); - return false; - } + const addRow = useCallback( + async (rowData) => { + if (!isConnectedRef) { + onErrorRef.current?.('Нет подключения или авторизации'); + return false; + } - const message = { - event: "row_added", - data: rowData, - }; - addCommonField(message); + const message = { + event: 'row_added', + data: rowData, + }; + addCommonField(message); - return sendMessage(message); - }, - [isConnected, sendMessage, sheetName, formId, direction], - ); + return sendMessage(message); + }, + [isConnected, sendMessage, sheetName, formId, direction], + ); - const addProject = useCallback( - async (rowData) => { - if (!isConnectedRef) { - onErrorRef.current?.("Нет подключения или авторизации"); - return false; - } + const addProject = useCallback( + async (rowData) => { + if (!isConnectedRef) { + onErrorRef.current?.('Нет подключения или авторизации'); + return false; + } - const message = { - event: "project_added", - data: rowData, - }; - addCommonField(message); + const message = { + event: 'project_added', + data: rowData, + }; + addCommonField(message); - return sendMessage(message); - }, - [isConnected, sendMessage, sheetName, formId, direction], - ); + return sendMessage(message); + }, + [isConnected, sendMessage, sheetName, formId, direction], + ); - const addProgram = useCallback( - async (rowData) => { - if (!isConnectedRef) { - onErrorRef.current?.("Нет подключения или авторизации"); - return false; - } + const addProgram = useCallback( + async (rowData) => { + if (!isConnectedRef) { + onErrorRef.current?.('Нет подключения или авторизации'); + return false; + } - const message = { - event: "program_added", - data: rowData, - }; - addCommonField(message); + const message = { + event: 'program_added', + data: rowData, + }; + addCommonField(message); - return sendMessage(message); - }, - [isConnected, sendMessage, sheetName, formId, direction], - ); + return sendMessage(message); + }, + [isConnected, sendMessage, sheetName, formId, direction], + ); - const deleteRow = useCallback( - async (rowId) => { - if (!isConnectedRef) { - onErrorRef.current?.("Нет подключения или авторизации"); - return false; - } + const deleteRow = useCallback( + async (rowId) => { + if (!isConnectedRef) { + onErrorRef.current?.('Нет подключения или авторизации'); + return false; + } - const message = { - event: "row_deleted", - data: { row_id: rowId }, - }; - addCommonField(message); + const message = { + event: 'row_deleted', + data: { row_id: rowId }, + }; + addCommonField(message); - return sendMessage(message); - }, - [isConnected, sendMessage, sheetName, formId, direction], - ); + return sendMessage(message); + }, + [isConnected, sendMessage, sheetName, formId, direction], + ); - const subscribeToCellUpdates = useCallback((callback) => { - onCellUpdateRef.current = callback; - return () => { - onCellUpdateRef.current = null; - }; - }, []); + const subscribeToCellUpdates = useCallback((callback) => { + onCellUpdateRef.current = callback; + return () => { + onCellUpdateRef.current = null; + }; + }, []); - const subscribeToRowAdds = useCallback((callback) => { - onRowAddRef.current = callback; - return () => { - onRowAddRef.current = null; - }; - }, []); + const subscribeToRowAdds = useCallback((callback) => { + onRowAddRef.current = callback; + return () => { + onRowAddRef.current = null; + }; + }, []); - const subscribeToRowDeletes = useCallback((callback) => { - onRowDeleteRef.current = callback; - return () => { - onRowDeleteRef.current = null; - }; - }, []); + const subscribeToRowDeletes = useCallback((callback) => { + onRowDeleteRef.current = callback; + return () => { + onRowDeleteRef.current = null; + }; + }, []); - const subscribeToProgramAdds = useCallback((callback) => { - onProgramAddRef.current = callback; - return () => { - onProgramAddRef.current = null; - }; - }, []); + const subscribeToProgramAdds = useCallback((callback) => { + onProgramAddRef.current = callback; + return () => { + onProgramAddRef.current = null; + }; + }, []); - const subscribeToProjectAdds = useCallback((callback) => { - onProjectAddRef.current = callback; - return () => { - onProjectAddRef.current = null; - }; - }, []); + const subscribeToProjectAdds = useCallback((callback) => { + onProjectAddRef.current = callback; + return () => { + onProjectAddRef.current = null; + }; + }, []); - const subscribeToErrors = useCallback((callback) => { - onErrorRef.current = callback; - return () => { - onErrorRef.current = null; - }; - }, []); + const subscribeToErrors = useCallback((callback) => { + onErrorRef.current = callback; + return () => { + onErrorRef.current = null; + }; + }, []); - const subscribeToAuthSuccess = useCallback((callback) => { - onAuthSuccessRef.current = callback; - return () => { - onAuthSuccessRef.current = null; - }; - }, []); + const subscribeToAuthSuccess = useCallback((callback) => { + onAuthSuccessRef.current = callback; + return () => { + onAuthSuccessRef.current = null; + }; + }, []); - const subscribeToCellEditStart = useCallback((callback) => { - onCellEditStartRef.current = callback; - return () => { - onCellEditStartRef.current = null; - }; - }, []); + const subscribeToCellEditStart = useCallback((callback) => { + onCellEditStartRef.current = callback; + return () => { + onCellEditStartRef.current = null; + }; + }, []); - const subscribeToCellEditEnd = useCallback((callback) => { - onCellEditEndRef.current = callback; - return () => { - onCellEditEndRef.current = null; - }; - }, []); + const subscribeToCellEditEnd = useCallback((callback) => { + onCellEditEndRef.current = callback; + return () => { + onCellEditEndRef.current = null; + }; + }, []); - const retryLogin = useCallback(() => { - if (isConnected) { - authAttemptedRef.current = false; - sendLogin(); - } - }, [isConnected, sendLogin]); + const retryLogin = useCallback(() => { + if (isConnected) { + authAttemptedRef.current = false; + sendLogin(); + } + }, [isConnected, sendLogin]); - return ( - releaseAllLocks(userId), - }} - > - {children} - - ); + return ( + releaseAllLocks(userId), + }}> + {children} + + ); }; diff --git a/web/src/components/RealtimeTable/tableColumns.jsx b/web/src/components/RealtimeTable/tableColumns.jsx index 43fb911..9e7717c 100644 --- a/web/src/components/RealtimeTable/tableColumns.jsx +++ b/web/src/components/RealtimeTable/tableColumns.jsx @@ -1,210 +1,205 @@ import React, { useEffect, useRef, useState, useMemo, useCallback } from 'react'; import { createPortal } from 'react-dom'; import { useParams } from 'react-router'; +import VspDropdownEditCell from './Cell/EditCell/VspDropdownEditCell'; import { useRealtime } from './contexts/RealtimeContext'; -const EditCellPortal = React.memo(({ - cell, - table, - EditCell, - onSaveStart, - onSaveEnd, - onError, - isEditable -}) => { - const { formId, formType, sheetName, direction } = useParams(); - const tableKey = `${formId}_${formType}_${sheetName}_${direction}`; - const ref = useRef(null); - const [refTbody, setRefTbody] = useState(null); - const [isSaving, setIsSaving] = useState(false); +const EditCellPortal = React.memo(({ cell, table, EditCell, onSaveStart, onSaveEnd, onError, isEditable }) => { + const { formId, formType, sheetName, direction } = useParams(); + const tableKey = `${formId}_${formType}_${sheetName}_${direction}`; + const ref = useRef(null); + const [refTbody, setRefTbody] = useState(null); + const [isSaving, _setIsSaving] = useState(false); - const { endEditing: contextEndEditing } = useRealtime(); + const { endEditing: contextEndEditing } = useRealtime(); - useEffect(() => { - if (ref.current) { - const tbodyRef = ref.current.offsetParent?.offsetParent?.offsetParent; - if (tbodyRef && tbodyRef !== refTbody) { - setRefTbody(tbodyRef); - } - } - }, []); + useEffect(() => { + if (ref.current) { + const tbodyRef = ref.current.offsetParent?.offsetParent?.offsetParent; + if (tbodyRef && tbodyRef !== refTbody) { + setRefTbody(tbodyRef); + } + } + }, []); - const handleChange = useCallback( (val) => { - table.setEditingCell(null); - try { - if (table.options.meta?.updateCell) { - const success = table.options.meta.updateCell( - cell.row, - cell.column, - val - ); - if (!success) { - console.error('Failed to update cell via WebSocket'); - onError?.('Не удалось сохранить изменение'); - } - } - } catch (error) { - console.error('Error updating cell:', error); - onError?.(error.message); - } - }, [table, cell, onError]); + const handleChange = useCallback( + (val) => { + table.setEditingCell(null); + try { + if (table.options.meta?.updateCell) { + const success = table.options.meta.updateCell(cell.row, cell.column, val); + if (!success) { + onError?.('Не удалось сохранить изменение'); + } + } + } catch (error) { + onError?.(error.message); + } + }, + [table, cell, onError], + ); - const editCellProps = useMemo(() => ({ - refCell: ref, - cell, - value: cell.getValue(), - disabled: !isEditable, - onChange: handleChange, - tableId: tableKey, - table, - cellId: `${cell.row.id}_${cell.column.id}`, - }), [cell, isEditable, handleChange, tableKey, table]); + const editCellProps = useMemo( + () => ({ + refCell: ref, + cell, + value: cell.getValue(), + disabled: !isEditable, + onChange: handleChange, + tableId: tableKey, + table, + cellId: `${cell.row.id}_${cell.column.id}`, + }), + [cell, isEditable, handleChange, tableKey, table], + ); - const portalContent = useMemo(() => { - if (!refTbody || isSaving) return null; - return createPortal( - , - refTbody - ); - }, [refTbody, isSaving, editCellProps, EditCell]); + const editType = cell.column.columnDef?.editType; - return ( - <> -
- {portalContent} - - ); + const portalContent = useMemo(() => { + if (!refTbody || isSaving) return null; + + if (editType === 'vsp_dropdown') { + return createPortal(, refTbody); + } + + return createPortal(, refTbody); + }, [refTbody, isSaving, editCellProps, EditCell, editType]); + + return ( + <> +
+ {portalContent} + + ); }); +export const getTableColumns = ({ Cell, EditCell, columnsConfig, onCellUpdateError, onCellNumberClick, isCellInvalid }) => { + const columnColors = { ...columnsConfig.colors }; + const columns = structuredClone(columnsConfig.columns); -export const getTableColumns = ({ - Cell, - EditCell, - columnsConfig, - onCellUpdateError, - onCellNumberClick, - isCellInvalid, -}) => { - const columnColors = { ...columnsConfig.colors }; - const columns = structuredClone(columnsConfig.columns); + const cellPropsCache = new WeakMap(); + const editPropsCache = new WeakMap(); - const cellPropsCache = new WeakMap(); - const editPropsCache = new WeakMap(); + const getCachedCellProps = (row, column, table) => { + const key = `${row.id}_${column.id}`; + const value = row.getValue(column.id); + const isInvalid = isCellInvalid?.(column.id, value, row.original) || false; - const getCachedCellProps = (row, column, table) => { - const key = `${row.id}_${column.id}`; - const value = row.getValue(column.id); - const isInvalid = isCellInvalid?.(column.id, value, row.original) || false; + if (!cellPropsCache.has(row)) { + cellPropsCache.set(row, {}); + } - if (!cellPropsCache.has(row)) { - cellPropsCache.set(row, {}); - } + const rowCache = cellPropsCache.get(row); + if (rowCache[key]) { + const cached = rowCache[key]; + const currentGlobalFilter = table.getState().globalFilter; + const currentColumnFilter = table.getState().columnFilters?.find((f) => f.id === column.id)?.value; - const rowCache = cellPropsCache.get(row); - if (rowCache[key]) { - const cached = rowCache[key]; - const currentGlobalFilter = table.getState().globalFilter; - const currentColumnFilter = table.getState().columnFilters?.find(f => f.id === column.id)?.value; + if ( + cached.globalFilter === currentGlobalFilter && + cached.columnFilter === currentColumnFilter && + cached.value === value && + cached.isInvalid === isInvalid + ) { + return cached; + } + } - if (cached.globalFilter === currentGlobalFilter && - cached.columnFilter === currentColumnFilter && - cached.value === value && - cached.isInvalid === isInvalid) { - return cached; - } - } + const globalFilter = table.getState().globalFilter; + const columnFilter = table.getState().columnFilters?.find((f) => f.id === column.id)?.value; - const globalFilter = table.getState().globalFilter; - const columnFilter = table.getState().columnFilters?.find(f => f.id === column.id)?.value; + const props = { + globalFilter, + columnFilter, + isEditable: row.original?.row_type === 'INPUT' || false, + backgroundColor: columnColors[column.id]?.color_type?.[row.original?.row_type || row.row_type], + isUpdating: table.options.meta?.updatingCells?.[`${row.id}_${column.id}`], + isInvalid, + value, + _hash: `${globalFilter}_${columnFilter}_${row.id}_${column.id}_${value}_${isInvalid}`, + }; - const props = { - globalFilter, - columnFilter, - isEditable: row.original?.row_type === 'INPUT' || false, - backgroundColor: columnColors[column.id]?.color_type?.[row.original?.row_type || row.row_type], - isUpdating: table.options.meta?.updatingCells?.[`${row.id}_${column.id}`], - isInvalid, - value, - _hash: `${globalFilter}_${columnFilter}_${row.id}_${column.id}_${value}_${isInvalid}`, - }; + rowCache[key] = props; + return props; + }; - rowCache[key] = props; - return props; - }; + const getCachedEditProps = (row, column, _table) => { + const key = `${row.id}_${column.id}`; - const getCachedEditProps = (row, column, table) => { - const key = `${row.id}_${column.id}`; + if (!editPropsCache.has(row)) { + editPropsCache.set(row, {}); + } - if (!editPropsCache.has(row)) { - editPropsCache.set(row, {}); - } + const rowCache = editPropsCache.get(row); + if (rowCache[key]) { + return rowCache[key]; + } - const rowCache = editPropsCache.get(row); - if (rowCache[key]) { - return rowCache[key]; - } + const props = { + isEditable: row.original?.row_type === 'INPUT' || false, + }; - const props = { - isEditable: row.original?.row_type === 'INPUT' || false, - }; + rowCache[key] = props; + return props; + }; - rowCache[key] = props; - return props; - }; + // Оптимизированная функция processColumns + const processColumns = (columns) => { + columns.forEach((col) => { + col.Cell = ({ cell, table, column, row }) => { + const { vspOptions } = useRealtime(); + const props = getCachedCellProps(row, column, table); - // Оптимизированная функция processColumns - const processColumns = (columns) => { - columns.forEach((col) => { - col.Cell = ({ cell, table, column, row }) => { - const props = getCachedCellProps(row, column, table); + const cellProps = useMemo( + () => ({ + row, + column, + cell, + vspOptions, + ...props, + }), + [row.id, column.id, cell.getValue(), props._hash, vspOptions], + ); - const cellProps = useMemo(() => ({ - row, - column, - cell, - ...props, - }), [row.id, column.id, cell.getValue(), props._hash]); + return ; + }; - return ; - }; + col.Edit = ({ cell, table, row, column }) => { + const props = getCachedEditProps(row, column, table); - col.Edit = ({ cell, table, row, column }) => { - const props = getCachedEditProps(row, column, table); + const editComponent = useMemo( + () => , + [cell, table, EditCell, onCellUpdateError, props.isEditable], + ); - const editComponent = useMemo(() => ( - - ), [cell, table, EditCell, onCellUpdateError, props.isEditable]); + return editComponent; + }; - return editComponent; - }; + if (col.editType === 'vsp_dropdown') { + col.enableEditing = (row) => row?.original?.row_type === 'INPUT'; + } - if (col.columns?.length) { - processColumns(col.columns); - } - }); - }; + if (col.columns?.length) { + processColumns(col.columns); + } + }); + }; - processColumns(columns); + processColumns(columns); - const rowNumber = { - accessorKey: 'sort_order', - header: '#', - size: 50, - enableEditing: false, - Cell: ({ cell, row }) => { - const handleClick = useCallback(() => { - onCellNumberClick(row.id); - }, [row.id, onCellNumberClick]); + const rowNumber = { + accessorKey: 'sort_order', + header: '#', + size: 50, + enableEditing: false, + Cell: ({ cell, row }) => { + const handleClick = useCallback(() => { + onCellNumberClick(row.id); + }, [row.id, onCellNumberClick]); - return ; - }, - }; + return ; + }, + }; - return [rowNumber, ...columns]; -}; \ No newline at end of file + return [rowNumber, ...columns]; +}; -- 2.47.2