import type { CheckResult, DocumentStatus, FileOut, FileType } from '../../types/api'; import { formatMoscowDate } from '../../utils/dates'; import { documentStatusLabel, documentTypeLabel, periodLabel } from '../../utils/labels'; export type RowStatus = 'success' | 'warning' | 'processing' | 'error'; export interface DocumentRow { key: string; /** id документа; null — строка файла без документов */ documentId: string | null; name: string; fileType: FileType; subtitle: string; period: string; periodCheck?: CheckResult | null; counterpartyCheck?: CheckResult | null; status: RowStatus; statusLabel: string; errorReason: string | null; linkable: boolean; } const LINKABLE = new Set(['OSV', 'BALANCE', 'INCOME']); const join = (parts: (string | null)[]) => parts.filter(Boolean).join(' · '); function errorReason(f: FileOut): string | null { if (f.status !== 'ERROR' || !f.job) return null; return f.job.mapping_error ?? f.job.error_message ?? f.job.error_code ?? null; } function documentRowStatus(status: DocumentStatus): RowStatus { if (status === 'CONFIRMED') return 'success'; if (status === 'ERROR') return 'error'; return 'warning'; } /** Файлы → строки таблицы: одна строка на документ, файл без документов — одна строка на файл. */ export function buildDocumentRows(files: FileOut[], labelFor?: (f: FileOut) => string | null): DocumentRow[] { return files.flatMap((f): DocumentRow[] => { const extra = labelFor?.(f) ?? null; const name = f.original_name ?? 'без имени'; const date = formatMoscowDate(f.uploaded_at); if (f.documents.length === 0) { const failed = f.status === 'ERROR'; return [ { key: f.id, documentId: null, name, fileType: f.file_type, subtitle: join([f.file_type, date, extra]), period: '—', status: failed ? 'error' : 'processing', statusLabel: failed ? 'Ошибка' : 'Обработка', errorReason: errorReason(f), linkable: false, }, ]; } return f.documents.map((d) => { const typeText = d.document_type === 'DISCLOSURE' || d.document_type === 'OTHER' ? 'Прочий документ' : documentTypeLabel(d.document_type, d.osv_account_code); const status = documentRowStatus(d.status); return { key: d.id, documentId: d.id, name, fileType: f.file_type, subtitle: join([typeText, f.file_type, date, extra]), period: periodLabel(d.period_year, d.period_quarter, d.is_cumulative), periodCheck: d.period_check, counterpartyCheck: d.counterparty_check, status, statusLabel: documentStatusLabel(d.status), errorReason: null, linkable: LINKABLE.has(d.document_type), }; }); }); }