243 lines
7.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Table, Typography } from 'antd';
import type { ColumnsType } from 'antd/es/table';
import type React from 'react';
import { useMemo } from 'react';
import type { GoodwillRow, GoodwillTableResponse, GoodwillTreeRow } from '../../../types/goodwill/goodwill';
import './ConsolidationGoodwillTable.css';
import { chessTableCellFormatValue } from '../../../utils/chessTableCellFormatValue';
import { getGoodwillColumns } from './config';
import { sumAmounts } from '../../../utils/money';
const { Text } = Typography;
interface ConsolidationGoodwillTableI {
data: GoodwillTableResponse | null;
loading: boolean;
decimals: number;
units: string;
toolbar?: React.ReactNode;
isFullscreen?: boolean;
isEditMode: boolean;
editedRows: Record<string, Partial<GoodwillRow>>;
onRowEdit: (rowId: string, field: keyof GoodwillRow, value: boolean | string) => void;
visibleKeys: string[];
}
export const ConsolidationGoodwillTable: React.FC<ConsolidationGoodwillTableI> = ({
data,
loading,
decimals,
units,
toolbar,
isFullscreen = false,
isEditMode,
editedRows,
onRowEdit,
visibleKeys,
}) => {
const treeData = useMemo(() => {
if (!data?.rows) return [];
const tree: GoodwillTreeRow[] = [];
const heads = new Map<string, GoodwillTreeRow>();
data.rows.forEach((row) => {
const headId = row.head_legal_entity.id;
if (!heads.has(headId)) {
const groupNode: GoodwillTreeRow = {
...row,
key: `head-${headId}`,
isGroup: true,
head_legal_entity: row.head_legal_entity,
subsidiary_legal_entity: { id: '', name: '' },
ownership_share: null,
financial_investment_amount: '0',
charter_capital_amount: '0',
additional_capital_amount: '0',
participation_amount: '0',
goodwill_amount: '0',
include_in_kfo: false,
comment: null,
updated_at: null,
updated_by: null,
children: [],
};
heads.set(headId, groupNode);
tree.push(groupNode);
}
const group = heads.get(headId)!;
group.children!.push({
...row,
key: `${headId}-${row.subsidiary_legal_entity.id}`,
});
});
tree.forEach((parent) => {
if (parent.children && parent.children.length > 0) {
const allChecked = parent.children.every((child) => editedRows[child.key]?.include_in_kfo ?? child.include_in_kfo);
parent.include_in_kfo = allChecked;
let totalFinInv = 0;
let totalParticipation = 0;
let totalCharter = 0;
let totalGoodwill = 0;
parent.children.forEach((child) => {
totalFinInv += Number(child.financial_investment_amount || 0);
totalParticipation += Number(child.participation_amount || 0);
totalCharter += Number(child.charter_capital_amount || 0);
totalGoodwill += Number(child.goodwill_amount || 0);
});
const groupTotalRow: GoodwillTreeRow = {
key: `total-${parent.key}`,
head_legal_entity: parent.head_legal_entity,
subsidiary_legal_entity: { id: '', name: 'Всего' },
isGroupTotal: true,
isGroup: false,
financial_investment_amount: String(totalFinInv),
participation_amount: String(totalParticipation),
charter_capital_amount: String(totalCharter),
goodwill_amount: String(totalGoodwill),
ownership_share: null,
additional_capital_amount: '0',
include_in_kfo: false,
comment: null,
updated_at: null,
updated_by: null,
};
parent.children.push(groupTotalRow);
}
});
return tree;
}, [data?.rows, editedRows]);
const columns: ColumnsType<GoodwillTreeRow> = useMemo(() => {
return getGoodwillColumns({ units, decimals, isEditMode, editedRows, onRowEdit });
}, [units, decimals, isEditMode, editedRows, onRowEdit]);
const visibleColumns = useMemo(() => {
return columns.filter((col) => visibleKeys.includes(col.key as string));
}, [columns, visibleKeys]);
const scrollY = isFullscreen ? 'calc(100vh - 200px)' : 'auto';
const renderSummary = () => {
if (!data?.rows) return null;
const totalFinInv = sumAmounts(data.rows.map((c) => c.financial_investment_amount)) ?? '0.00';
const totalParticipation = sumAmounts(data.rows.map((c) => c.participation_amount)) ?? '0.00';
const totalCharter = sumAmounts(data.rows.map((c) => c.charter_capital_amount)) ?? '0.00';
const totalGoodwill = sumAmounts(data.rows.map((c) => c.goodwill_amount)) ?? '0.00';
return (
<Table.Summary fixed>
<Table.Summary.Row className='resRow'>
{visibleColumns.map((col, index) => {
if (col.key === 'include_in_kfo') {
return (
<Table.Summary.Cell key={col.key} index={index} align='center'>
<Text strong>—</Text>
</Table.Summary.Cell>
);
}
if (col.key === 'name') {
return (
<Table.Summary.Cell key={col.key} index={index} align='left'>
<div style={{ backgroundColor: '#e6f4ea', width: '100%', height: '100%' }}>
<Text strong>Итого по листу</Text>
</div>
</Table.Summary.Cell>
);
}
if (col.key === 'ownership_share') {
return (
<Table.Summary.Cell key={col.key} index={index} align='right'>
<Text strong>—</Text>
</Table.Summary.Cell>
);
}
if (col.key === 'financial_investment_amount') {
return (
<Table.Summary.Cell key={col.key} index={index} align='right'>
<div style={{ backgroundColor: '#e6f4ea' }}>
<Text strong>{chessTableCellFormatValue(String(totalFinInv), units, decimals)}</Text>
</div>
</Table.Summary.Cell>
);
}
if (col.key === 'participation_amount') {
return (
<Table.Summary.Cell key={col.key} index={index} align='right'>
<div style={{ backgroundColor: '#e6f4ea' }}>
<Text strong>{chessTableCellFormatValue(String(totalParticipation), units, decimals)}</Text>
</div>
</Table.Summary.Cell>
);
}
if (col.key === 'charter_capital_amount') {
return (
<Table.Summary.Cell key={col.key} index={index} align='right'>
<div style={{ backgroundColor: '#e6f4ea' }}>
<Text strong>{chessTableCellFormatValue(String(totalCharter), units, decimals)}</Text>
</div>
</Table.Summary.Cell>
);
}
if (col.key === 'goodwill_amount') {
return (
<Table.Summary.Cell key={col.key} index={index} align='right'>
<div style={{ backgroundColor: '#e6f4ea' }}>
<Text strong>{chessTableCellFormatValue(String(totalGoodwill), units, decimals)}</Text>
</div>
</Table.Summary.Cell>
);
}
if (col.key === 'comment') {
return (
<Table.Summary.Cell key={col.key} index={index} align='right'>
<Text strong>—</Text>
</Table.Summary.Cell>
);
}
return null;
})}
</Table.Summary.Row>
</Table.Summary>
);
};
return (
<Table<GoodwillTreeRow>
className='goodwillTable'
dataSource={treeData}
columns={visibleColumns}
rowKey='key'
pagination={false}
loading={loading}
scroll={{ x: 'max-content', y: scrollY }}
size='small'
bordered
title={() => toolbar}
key={data?.rows?.length}
expandable={{ defaultExpandAllRows: true }}
summary={renderSummary}
rowClassName={(record) => (record.isGroupTotal ? 'group-total-row' : '')}
/>
);
};