// Чистые правила экранов консолидаций (спека `consolidations-ui`): подписи и пояснения статусов версии, ручные // переходы, блокировка, «Версия», фильтр «Только в работе». Без React, store и API. import type { ConsRussianStatus, ConsStatus, LockOut } from '../types/consolidations/common_types'; /** Подписи статусов версии — одни для списка, фильтра «Статус», шапки карточки и модалки «Изменить статус». */ export const CONS_STATUS_LABEL: Record = { INITIATED: 'Инициация', DOCUMENTS_PROCESSING: 'Обработка документов', DATA_CORRECTION: 'Корректировка данных', CONSOLIDATION_RF: 'Консолидация РФ', VERIFICATION_RF: 'Верификация РФ', CONSOLIDATION_GO: 'Консолидация ГО', VERIFICATION_GO: 'Верификация ГО', VERIFIED: 'Верифицирован', CANCELLED: 'Отменена', ADJUSTMENT: 'Корректировка', ARCHIVED: 'В архиве', REJECTED: 'Отклонён', }; /** * Пояснение статуса под заголовком карточки версии. `CONSOLIDATION_RF`, `VERIFIED` — тексты макета [30], [33-01]; * `INITIATED`, `DOCUMENTS_PROCESSING`, `DATA_CORRECTION`, `CANCELLED` — временные из ТЗ «Статусная модель», пока нет * текстов аналитика (design.md change consolidations-ui, решение (б)). */ export const CONS_STATUS_DESCRIPTION: Partial> = { INITIATED: 'Система зафиксировала состав ГСК на отчетную дату и инициатора (КА РФ или КА ГО)', DOCUMENTS_PROCESSING: 'КА загружает документы; система отправляет pdf файлы в ИС Сканирование, производит парсинг ОСВ, бухгалтерского баланса и ОФР', DATA_CORRECTION: 'Выявлены некорректные данные в ИС Сканирование, проводится ручная корректировка. Пользователь валидирует распарсенные данные и вносит правки', CONSOLIDATION_RF: 'Автоматическая консолидация, ручные проверки и сравнение КФО клиента и банка', CONSOLIDATION_GO: 'Формирование и проверка КФО, внесение корректировок на уровне ГО', VERIFICATION_RF: 'Проверка и подтверждение КФО на уровне РФ', VERIFICATION_GO: 'Проверка и подтверждение КФО на уровне ГО', VERIFIED: 'Отчет верифицирован ГО, КА ГО внес в систему номер и дату решения УОБ', CANCELLED: 'Заявка на формирование/подтверждение КФО аннулирована по инициативе пользователя', }; /** Пояснение статуса; нет текста — пусто (название статуса под заголовком не повторяем). */ export const consStatusDescription = (status: ConsStatus): string => CONS_STATUS_DESCRIPTION[status] ?? ''; /** * Ручные переходы статуса версии — зеркало `MANUAL_TRANSITIONS` из `api/src/services/consolidation_status.py` * (API допустимые переходы не отдаёт). Расхождение с бэком сервер ловит 409 `TRANSITION_NOT_ALLOWED`. С маршрутом * согласования (Срез 7) заменяется ответом API. */ export const MANUAL_TRANSITIONS: Partial> = { INITIATED: ['CANCELLED'], DOCUMENTS_PROCESSING: ['CANCELLED', 'INITIATED'], DATA_CORRECTION: ['CANCELLED', 'INITIATED'], }; /** Допустимые ручные переходы из статуса; нет — пустой список. */ export const manualTransitions = (status: ConsStatus): readonly ConsStatus[] => MANUAL_TRANSITIONS[status] ?? []; /** Версию держит текущий пользователь. */ export const isLockedBy = (lock: LockOut | null | undefined, userId: string): boolean => !!lock && lock.locked_by === userId; /** Кнопка «Изменить статус» в шапке карточки: своя блокировка и есть ручные переходы. */ export const canChangeStatus = (status: ConsStatus, lock: LockOut | null | undefined, userId: string): boolean => isLockedBy(lock, userId) && manualTransitions(status).length > 0; /** Лимит причины перехвата и комментария к смене статуса (`MAX_TAKEOVER_REASON`, `MAX_STATUS_COMMENT` бэка). */ export const MAX_REASON_LENGTH = 1000; /** Причина перехвата / комментарий: непусто после обрезки пробелов и не длиннее лимита. */ export const isValidReason = (text: string | null | undefined): boolean => { const trimmed = (text ?? '').trim(); return trimmed.length > 0 && trimmed.length <= MAX_REASON_LENGTH; }; /** «Изменить статус» в модалке: выбран новый этап и комментарий непуст. */ export const canSubmitStatusChange = (toStatus: ConsStatus | null | undefined, comment: string | null | undefined): boolean => !!toStatus && isValidReason(comment); /** Колонка «Версия»: у первой версии пусто, у последующих — номер. */ export const versionLabel = (versionNo: number): string => (versionNo === 1 ? '' : String(versionNo)); /** Флажок «Только в работе» из `?in_work_only=`: включён только явным `true` (по умолчанию выключен, как в API). */ export const parseInWorkOnly = (param: string | null): boolean => param === 'true'; /** «Взять в работу» недоступна у отменённой версии — по коду статуса, а не по подписи. */ export const canTakeInWork = (status: ConsStatus): boolean => status !== 'CANCELLED'; /** Точка в конце фразы после ФИО: «Соколов А. В.» уже заканчивается точкой — вторую не ставим. */ export const endSentence = (text: string): string => (text.endsWith('.') ? text : `${text}.`); /** «+ Создать» в модалке «Новая консолидация»: в консолидации не меньше двух ЮЛ (иначе 422 `PERIMETER_TOO_SMALL`). */ export const MIN_PERIMETER = 2; /** Модалка [31-00] нужна при уходе со вкладки «ОСВ», пока есть несопоставленные строки. */ export const needsUnmappedWarning = (unmappedTotal: number | null | undefined): boolean => (unmappedTotal ?? 0) > 0;