546 lines
14 KiB
JavaScript
546 lines
14 KiB
JavaScript
import { Box, IconButton, Tooltip } from '@mui/material';
|
||
import { Back, EditPenSvg, TrashSvg } from '../../components/common/icons/icons';
|
||
import StatusBadge from './components/StatusBadge/StatusBadge';
|
||
import { DEVELOMENT_BLOCK, FUNDING_BY_DECISION } from './constants';
|
||
|
||
export const createFirstColumns = (handlers) => {
|
||
const { onDelete, onEdit, onNavigate, orgUnitNames = {} } = handlers;
|
||
return [
|
||
{
|
||
id: 'project',
|
||
accessorFn: (row) => {
|
||
const projectName = row.name ?? row.project ?? '';
|
||
const orgUnitName = orgUnitNames[row.org_unit_id] ?? row.org_unit_id;
|
||
return orgUnitName ? `${projectName} / ${orgUnitName}` : projectName;
|
||
},
|
||
header: 'Проект',
|
||
size: 200,
|
||
filterFn: 'contains',
|
||
filterVariant: 'text',
|
||
},
|
||
{
|
||
accessorKey: 'status',
|
||
header: 'Статус',
|
||
size: 100,
|
||
Cell: ({ cell }) => {
|
||
const status = cell.getValue();
|
||
return <StatusBadge status={status} />;
|
||
},
|
||
},
|
||
{
|
||
accessorKey: 'technical_number',
|
||
header: 'Технический номер проекта',
|
||
size: 150,
|
||
},
|
||
{
|
||
accessorKey: 'object_address',
|
||
header: 'Адрес объекта',
|
||
size: 180,
|
||
},
|
||
{
|
||
accessorKey: 'vsp_format',
|
||
header: 'Формат ВСП',
|
||
size: 150,
|
||
Cell: ({ cell }) => cell.getValue() ?? '',
|
||
},
|
||
{
|
||
accessorKey: 'krf_decision_date',
|
||
header: 'Дата решения КРФ',
|
||
size: 160,
|
||
},
|
||
{
|
||
accessorKey: 'fk_decision_date',
|
||
header: 'Дата решения ФК',
|
||
size: 120,
|
||
},
|
||
{
|
||
accessorKey: 'board_decision_date',
|
||
header: 'Дата решения Правления',
|
||
size: 130,
|
||
},
|
||
{
|
||
accessorKey: 'open_relocate_close_date',
|
||
header: 'Дата открытия / переезда / закрытия',
|
||
size: 160,
|
||
},
|
||
{
|
||
accessorKey: 'project_type',
|
||
header: 'Тип проекта',
|
||
size: 130,
|
||
},
|
||
{
|
||
accessorKey: 'funding_by_ko_decision',
|
||
header: 'Финансирование по решению КО',
|
||
size: 150,
|
||
Cell: ({ cell }) => FUNDING_BY_DECISION.find((v) => v[0] === cell.getValue())?.[1] || '-',
|
||
},
|
||
{
|
||
accessorKey: 'year',
|
||
header: 'Год сметы',
|
||
size: 130,
|
||
},
|
||
{
|
||
accessorKey: 'is_in_plan',
|
||
header: 'В базовой смете',
|
||
size: 140,
|
||
Cell: ({ cell }) => formatBooleanIsPlan(cell.getValue()),
|
||
},
|
||
{
|
||
accessorKey: 'is_in_plan_q2',
|
||
header: 'В скоррект смете 2 кв.',
|
||
size: 140,
|
||
Cell: ({ cell }) => formatBooleanIsPlan(cell.getValue()),
|
||
|
||
},
|
||
{
|
||
accessorKey: 'is_in_plan_q3',
|
||
header: 'В скоррект смете 3 кв.',
|
||
size: 140,
|
||
Cell: ({ cell }) => formatBooleanIsPlan(cell.getValue()),
|
||
},
|
||
{
|
||
accessorKey: 'is_in_plan_q4',
|
||
header: 'В скоррект смете 4 кв.',
|
||
size: 140,
|
||
Cell: ({ cell }) => formatBooleanIsPlan(cell.getValue()),
|
||
},
|
||
{
|
||
accessorKey: 'development_block',
|
||
header: 'Блок развития',
|
||
size: 120,
|
||
Cell: ({ cell }) => DEVELOMENT_BLOCK.find((v) => v[0] === cell.getValue())?.[1] || '-',
|
||
},
|
||
{
|
||
accessorKey: 'reserve_to_prrs_ahr',
|
||
header: 'Из резерва Банка в смету ПРРС АХР',
|
||
size: 160,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
{
|
||
accessorKey: 'reserve_to_prrs_kv',
|
||
header: 'Из резерва Банка в смету ПРРС кв.',
|
||
size: 160,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
{
|
||
accessorKey: 'actions',
|
||
header: '',
|
||
size: 120,
|
||
enableSorting: false,
|
||
Cell: ({ row }) => (
|
||
<Box sx={{ display: 'flex', gap: 0.5 }}>
|
||
<Tooltip title='Редактировать'>
|
||
<IconButton
|
||
variant='outlined'
|
||
onClick={(e) => {
|
||
e.stopPropagation();
|
||
onEdit(row);
|
||
}}>
|
||
<EditPenSvg />
|
||
</IconButton>
|
||
</Tooltip>
|
||
|
||
{row.depth == 0 && (
|
||
<>
|
||
<Tooltip title='Перейти'>
|
||
<IconButton
|
||
variant='outlined'
|
||
onClick={(e) => {
|
||
e.stopPropagation();
|
||
onNavigate(row);
|
||
}}>
|
||
<Back style={{ transform: 'scaleX(-1)' }} />
|
||
</IconButton>
|
||
</Tooltip>
|
||
<Tooltip title='Удалить проект'>
|
||
<IconButton
|
||
variant='outlined'
|
||
color='error'
|
||
onClick={(e) => {
|
||
e.stopPropagation();
|
||
onDelete(row.original);
|
||
}}>
|
||
<TrashSvg fill='currentColor' />
|
||
</IconButton>
|
||
</Tooltip>
|
||
</>
|
||
)}
|
||
</Box>
|
||
),
|
||
},
|
||
];
|
||
};
|
||
|
||
// Колонки для второй таблицы с многоуровневыми заголовками
|
||
export const secondColumns = [
|
||
{
|
||
accessorKey: 'data.header.name',
|
||
header: 'Проект',
|
||
size: 120,
|
||
sticky: 'left',
|
||
Cell: ({ cell, row }) => row.original.data?.header?.year ? `Смета_${row.original.data.header.year}` : cell.getValue(),
|
||
},
|
||
// Объем финансирования по контрольному листу
|
||
{
|
||
header: 'Объем финансирования по контрольному листу',
|
||
columns: [
|
||
{
|
||
accessorKey: 'data.financing.ahr',
|
||
header: 'АХР',
|
||
size: 100,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
{
|
||
accessorKey: 'data.financing.ahr_limit',
|
||
header: 'АХР лимит',
|
||
size: 100,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
{
|
||
accessorKey: 'data.financing.ahr_current',
|
||
header: 'АХР текущие',
|
||
size: 100,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
{
|
||
accessorKey: 'data.financing.kv',
|
||
header: 'кв.',
|
||
size: 100,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
],
|
||
},
|
||
// Базовый период
|
||
{
|
||
header: 'Базовый период 01.01 - 31.03',
|
||
columns: [
|
||
{
|
||
accessorKey: 'data.base_q1.ahr',
|
||
header: 'АХР',
|
||
size: 100,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
{
|
||
accessorKey: 'data.base_q1.ahr_limit',
|
||
header: 'АХР лимит',
|
||
size: 100,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
{
|
||
accessorKey: 'data.base_q1.ahr_current',
|
||
header: 'АХР текущие',
|
||
size: 100,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
{
|
||
accessorKey: 'data.base_q1.kv',
|
||
header: 'кв.',
|
||
size: 100,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
],
|
||
},
|
||
// Скорректированный период Q2
|
||
{
|
||
header: 'Скорректированный период 01.04 - 30.06',
|
||
columns: [
|
||
{
|
||
accessorKey: 'data.corrected_q2.ahr',
|
||
header: 'АХР',
|
||
size: 100,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
{
|
||
accessorKey: 'data.corrected_q2.ahr_limit',
|
||
header: 'АХР лимит',
|
||
size: 100,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
{
|
||
accessorKey: 'data.corrected_q2.ahr_current',
|
||
header: 'АХР текущие',
|
||
size: 100,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
{
|
||
accessorKey: 'data.corrected_q2.kv',
|
||
header: 'кв.',
|
||
size: 100,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
],
|
||
},
|
||
// Скорректированный период Q3
|
||
{
|
||
header: 'Скорректированный период 01.07 - 30.09',
|
||
columns: [
|
||
{
|
||
accessorKey: 'data.corrected_q3.ahr',
|
||
header: 'АХР',
|
||
size: 100,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
{
|
||
accessorKey: 'data.corrected_q3.ahr_limit',
|
||
header: 'АХР лимит',
|
||
size: 100,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
{
|
||
accessorKey: 'data.corrected_q3.ahr_current',
|
||
header: 'АХР текущие',
|
||
size: 100,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
{
|
||
accessorKey: 'data.corrected_q3.kv',
|
||
header: 'кв.',
|
||
size: 100,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
],
|
||
},
|
||
// Скорректированный период Q4
|
||
{
|
||
header: 'Скорректированный период 01.10 - 31.12',
|
||
columns: [
|
||
{
|
||
accessorKey: 'data.corrected_q4.ahr',
|
||
header: 'АХР',
|
||
size: 100,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
{
|
||
accessorKey: 'data.corrected_q4.ahr_limit',
|
||
header: 'АХР лимит',
|
||
size: 100,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
{
|
||
accessorKey: 'data.corrected_q4.ahr_current',
|
||
header: 'АХР текущие',
|
||
size: 100,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
{
|
||
accessorKey: 'data.corrected_q4.kv',
|
||
header: 'кв.',
|
||
size: 100,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
],
|
||
},
|
||
// Фактические расходы (АХР)
|
||
{
|
||
header: 'Фактические расходы (АХР)',
|
||
columns: [
|
||
{
|
||
header: '1 кв.артал',
|
||
columns: [
|
||
{
|
||
accessorKey: 'data.actual_ahr.q1.ahr',
|
||
header: 'Фактические расходы',
|
||
size: 120,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
{
|
||
accessorKey: 'data.actual_ahr.q1.ahr_limit',
|
||
header: 'Лимит',
|
||
size: 80,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
{
|
||
accessorKey: 'data.actual_ahr.q1.ahr_current',
|
||
header: 'Текущие',
|
||
size: 80,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
],
|
||
},
|
||
{
|
||
header: '2 кв.артал',
|
||
columns: [
|
||
{
|
||
accessorKey: 'data.actual_ahr.q2.ahr',
|
||
header: 'Фактические расходы',
|
||
size: 120,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
{
|
||
accessorKey: 'data.actual_ahr.q2.ahr_limit',
|
||
header: 'Лимит',
|
||
size: 80,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
{
|
||
accessorKey: 'data.actual_ahr.q2.ahr_current',
|
||
header: 'Текущие',
|
||
size: 80,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
],
|
||
},
|
||
{
|
||
header: '3 кв.артал',
|
||
columns: [
|
||
{
|
||
accessorKey: 'data.actual_ahr.q3.ahr',
|
||
header: 'Фактические расходы',
|
||
size: 120,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
{
|
||
accessorKey: 'data.actual_ahr.q3.ahr_limit',
|
||
header: 'Лимит',
|
||
size: 80,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
{
|
||
accessorKey: 'data.actual_ahr.q3.ahr_current',
|
||
header: 'Текущие',
|
||
size: 80,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
],
|
||
},
|
||
{
|
||
header: '4 кв.артал',
|
||
columns: [
|
||
{
|
||
accessorKey: 'data.actual_ahr.q4.ahr',
|
||
header: 'Фактические расходы',
|
||
size: 120,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
{
|
||
accessorKey: 'data.actual_ahr.q4.ahr_limit',
|
||
header: 'Лимит',
|
||
size: 80,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
{
|
||
accessorKey: 'data.actual_ahr.q4.ahr_current',
|
||
header: 'Текущие',
|
||
size: 80,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
],
|
||
},
|
||
],
|
||
},
|
||
// Фактические расходы (кв.)
|
||
{
|
||
header: 'Фактические расходы (кв.)',
|
||
columns: [
|
||
{
|
||
header: '1 кв.артал',
|
||
columns: [
|
||
{
|
||
accessorKey: 'data.actual_kv.q1.kv',
|
||
header: 'Фактические расходы',
|
||
size: 120,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
{
|
||
accessorKey: 'data.actual_kv.q1.kv_limit',
|
||
header: 'Лимит',
|
||
size: 80,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
{
|
||
accessorKey: 'data.actual_kv.q1.kv_current',
|
||
header: 'Текущие',
|
||
size: 80,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
],
|
||
},
|
||
{
|
||
header: '2 кв.артал',
|
||
columns: [
|
||
{
|
||
accessorKey: 'data.actual_kv.q2.kv',
|
||
header: 'Фактические расходы',
|
||
size: 120,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
{
|
||
accessorKey: 'data.actual_kv.q2.kv_limit',
|
||
header: 'Лимит',
|
||
size: 80,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
{
|
||
accessorKey: 'data.actual_kv.q2.kv_current',
|
||
header: 'Текущие',
|
||
size: 80,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
],
|
||
},
|
||
{
|
||
header: '3 кв.артал',
|
||
columns: [
|
||
{
|
||
accessorKey: 'data.actual_kv.q3.kv',
|
||
header: 'Фактические расходы',
|
||
size: 120,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
{
|
||
accessorKey: 'data.actual_kv.q3.kv_limit',
|
||
header: 'Лимит',
|
||
size: 80,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
{
|
||
accessorKey: 'data.actual_kv.q3.kv_current',
|
||
header: 'Текущие',
|
||
size: 80,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
],
|
||
},
|
||
{
|
||
header: '4 кв.артал',
|
||
columns: [
|
||
{
|
||
accessorKey: 'data.actual_kv.q4.kv',
|
||
header: 'Фактические расходы',
|
||
size: 120,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
{
|
||
accessorKey: 'data.actual_kv.q4.kv_limit',
|
||
header: 'Лимит',
|
||
size: 80,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
{
|
||
accessorKey: 'data.actual_kv.q4.kv_current',
|
||
header: 'Текущие',
|
||
size: 80,
|
||
Cell: ({ cell }) => formatNumber(cell.getValue()),
|
||
},
|
||
],
|
||
},
|
||
],
|
||
},
|
||
];
|
||
|
||
const formatBoolean = (value) => {
|
||
if (value === null || value === undefined) return '';
|
||
return value ? 'Да' : 'Нет';
|
||
};
|
||
|
||
const formatBooleanIsPlan = (value) => {
|
||
if (value === null || value === undefined) return '';
|
||
return value ? 'В плане' : '';
|
||
};
|
||
|
||
const formatNumber = (value) => {
|
||
if (value === null || value === undefined || value === '') return '';
|
||
const number = Number(value);
|
||
return Number.isNaN(number) ? value : number.toLocaleString('ru-RU');
|
||
};
|