import { EditOutlined, FullscreenExitOutlined, FullscreenOutlined } from '@ant-design/icons'; import { Alert, Button, ConfigProvider, Select, Space, Tooltip } from 'antd'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { useParams } from 'react-router-dom'; import type { GoodwillRow, GoodwillTableResponse } from '../../../types/goodwill/goodwill'; import { useNotificationApi } from '../../../utils/useNotification'; import { ConsolidationChessFormatTableFilter } from '../../ConsolidationChess/ConsolidationChessFormatTableFilter/ConsolidationChessFormatTableFilter'; import { ConsolidationGoodwillTable } from '../ConsolidationGoodwillTable/ConsolidationGoodwillTable'; import { getGoodwillColumns } from '../ConsolidationGoodwillTable/config'; import { ColumnSettings, useVisibleColumns } from '../../../components/GenericTable'; import { ApiError } from '../../../api/client'; // --- ТЕСТОВЫЕ ДАННЫЕ --- const MOCK_DATA: GoodwillTableResponse = { version_id: '30d45049-4dd6-4479-9cf7-33f4e71301ef', goodwill_enabled: true, editable: true, read_only_reason: null, rows: [ { head_legal_entity: { id: 'head-1', name: 'Агрохолдинг "Просторы" АО' }, subsidiary_legal_entity: { id: 'sub-1-1', name: 'ООО "Дон Агро"' }, ownership_share: '100.0000', financial_investment_amount: '4060.00', charter_capital_amount: '371.17', additional_capital_amount: '0.00', participation_amount: '371.14', goodwill_amount: '3688.86', include_in_kfo: true, comment: 'Основная дочерняя компания', updated_by: { id: 'user-1', name: 'Иванов И.И.' }, updated_at: '2026-10-15T10:00:00Z', }, { head_legal_entity: { id: 'head-1', name: 'Агрохолдинг "Просторы" АО' }, subsidiary_legal_entity: { id: 'sub-1-2', name: 'АО "Дон Агро"' }, ownership_share: '75.0000', financial_investment_amount: '260.01', charter_capital_amount: '120.00', additional_capital_amount: '0.00', participation_amount: '119.99', goodwill_amount: '-140.02', include_in_kfo: false, comment: null, updated_by: null, updated_at: null, }, { head_legal_entity: { id: 'head-1', name: 'Агрохолдинг "Просторы" АО' }, subsidiary_legal_entity: { id: 'sub-1-3', name: 'ООО "Дон Мучнов"' }, ownership_share: '100.0000', financial_investment_amount: '130.00', charter_capital_amount: '0.01', additional_capital_amount: '0.00', participation_amount: '0.01', goodwill_amount: '129.99', include_in_kfo: true, comment: '', updated_by: null, updated_at: null, }, { head_legal_entity: { id: 'head-1', name: 'Агрохолдинг "Просторы" АО' }, subsidiary_legal_entity: { id: 'sub-1-4', name: 'ООО "Инвестком"' }, ownership_share: '100.0000', financial_investment_amount: '267.00', charter_capital_amount: '0.01', additional_capital_amount: '0.00', participation_amount: '0.01', goodwill_amount: '266.99', include_in_kfo: false, comment: null, updated_by: null, updated_at: null, }, { head_legal_entity: { id: 'head-2', name: 'Инвестком АО' }, subsidiary_legal_entity: { id: 'sub-2-1', name: 'ООО "Юг-Инвест"' }, ownership_share: '50.0000', financial_investment_amount: '8500.00', charter_capital_amount: '1000.00', additional_capital_amount: '500.00', participation_amount: '500.00', goodwill_amount: '8000.00', include_in_kfo: true, comment: 'Требует пересмотра', updated_by: { id: 'user-2', name: 'Петров П.П.' }, updated_at: '2026-10-20T14:30:00Z', }, ], totals: { financial_investment_amount: '13217.01', participation_amount: '991.15', goodwill_amount: '12225.86', goodwill_in_kfo_amount: '11817.85', }, }; // ------------------------ export const GoodwillContent = () => { const { version_id } = useParams<{ version_id: string }>(); const notification = useNotificationApi(); const [data, setData] = useState(null); const [loading, setLoading] = useState(false); const [saving, setSaving] = useState(false); const [decimals, setDecimals] = useState(2); const [units, setUnits] = useState('thousand'); const [isEditMode, setIsEditMode] = useState(false); const [editedRows, setEditedRows] = useState>>({}); const goodwillTableRef = useRef(null); const [isGoodwillFullscreen, setIsGoodwillFullscreen] = useState(false); const [goodwillFilter, setGoodwillFilter] = useState('allValue'); const handleRowEdit = useCallback( (rowKey: string, field: keyof GoodwillRow, value: any) => { const isParent = rowKey.startsWith('head-') && !rowKey.includes('-sub-'); if (isParent && field === 'include_in_kfo') { const headId = rowKey.replace('head-', ''); const children = data?.rows.filter((r) => r.head_legal_entity.id === headId) || []; setEditedRows((prev) => { const next = { ...prev }; children.forEach((child) => { const childKey = `${headId}-${child.subsidiary_legal_entity.id}`; next[childKey] = { ...next[childKey], include_in_kfo: value }; }); return next; }); return; } setEditedRows((prev) => ({ ...prev, [rowKey]: { ...prev[rowKey], [field]: value }, })); }, [data?.rows], ); const columns = useMemo(() => { return getGoodwillColumns({ units, decimals, isEditMode, editedRows, onRowEdit: handleRowEdit }); }, [units, decimals, isEditMode, editedRows, handleRowEdit]); const groupsConfig = useMemo(() => { return { rowKey: 'key' as any, columns: columns as any }; }, [columns]); const { visibleKeys, setVisibleKeys } = useVisibleColumns(groupsConfig); const toggleFullscreen = async (ref: React.RefObject, setFullscreen: (val: boolean) => void) => { if (!ref.current) return; try { if (!document.fullscreenElement) { await ref.current.requestFullscreen(); setFullscreen(true); } else { await document.exitFullscreen(); setFullscreen(false); } } catch (e) { notification.error({ description: e instanceof Error ? e.message : 'Ошибка' }); } }; const dropFiltersHandler = () => { setGoodwillFilter('allValue'); }; const loadData = useCallback(async () => { setLoading(true); try { await new Promise((resolve) => setTimeout(resolve, 500)); setData(MOCK_DATA); const initialEdited: Record> = {}; MOCK_DATA.rows.forEach((row) => { if (row.include_in_kfo) { const key = `${row.head_legal_entity.id}-${row.subsidiary_legal_entity.id}`; initialEdited[key] = { include_in_kfo: true, ownership_share: row.ownership_share, comment: row.comment, }; } }); setEditedRows(initialEdited); } catch (e) { if (e instanceof ApiError) { notification.error({ description: e.message }); } } finally { setLoading(false); } }, [notification]); const handleSave = async () => { setSaving(true); try { await new Promise((resolve) => setTimeout(resolve, 800)); notification.success({ description: 'Изменения сохранены (тестовый режим)' }); setEditedRows({}); setIsEditMode(false); loadData(); } catch (e) { if (e instanceof ApiError) { notification.error({ description: e.message }); } } finally { setSaving(false); } }; const filteredData = useMemo(() => { if (!data) return null; if (goodwillFilter === 'allValue') return data; const filteredRows = data.rows.filter((row) => { const amount = Number(row.goodwill_amount); if (goodwillFilter === 'positive') return amount > 0; if (goodwillFilter === 'negative') return amount < 0; return true; }); return { ...data, rows: filteredRows, }; }, [data, goodwillFilter]); const canSaveEditData = useMemo(() => { if (!isEditMode) { return; } const hasErrors = Object.values(editedRows).some((elem) => { if (!elem.include_in_kfo) return false; const isShareEmpty = !elem.ownership_share || String(elem.ownership_share).trim() === ''; const isCommentEmpty = !elem.comment || String(elem.comment).trim() === ''; return isShareEmpty || isCommentEmpty; }); return !hasErrors; }, [editedRows, isEditMode]); useEffect(() => { loadData(); }, [loadData]); return ( (document.fullscreenElement as HTMLElement) || document.body}>
{isEditMode && ( Доступны для редактирования столбцы 'Доля владения' и 'Комментарий'.} type='warning' action={ } /> )}
Гудвил