import React, { useState } from 'react'; // FIX: Added missing ChevronRight import import { Search, ShieldCheck, AlertTriangle, Info, ShieldAlert, CheckCircle2, History, ChevronRight, Loader2, X, FileText, Phone, Mail } from 'lucide-react'; import { authFetch } from '../../services/apiClient'; interface LicenseItem { number?: string; series?: string; validFrom?: number; validTo?: number; activities?: string[]; issueAuthority?: string; } interface CounterpartyCheckResult { inn: string; kpp?: string; ogrn?: string; name: string; shortName?: string; type: string; status: string; registrationDate?: string; liquidationDate?: string; address?: string; okved?: string; okveds?: any[]; management?: { name: string; post?: string; }; finance?: { taxSystem?: string; income?: number; revenue?: number; expense?: number; debt?: number; penalty?: number; year?: number; }; authorities?: any; phones?: any[]; emails?: any[]; employeeCount?: number; capital?: { type?: string; value?: number }; smb?: { category?: string; issueDate?: number }; licenses?: LicenseItem[]; addressInvalidity?: any; foundersInvalidity?: Array<{ name?: string; invalidity?: any }>; managersInvalidity?: Array<{ name?: string; post?: string; invalidity?: any }>; managementDisqualified?: boolean; riskLevel: 'low' | 'medium' | 'high'; riskReasons: string[]; checkedDate: string; rawData?: any; } export const ComplianceCheck: React.FC = () => { const [inn, setInn] = useState(''); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [checkResult, setCheckResult] = useState(null); const [checkedCounterparties, setCheckedCounterparties] = useState([]); const [loadingHistory, setLoadingHistory] = useState(true); const [selectedReport, setSelectedReport] = useState(null); const [showReportModal, setShowReportModal] = useState(false); // Загружаем историю проверок при монтировании компонента React.useEffect(() => { loadHistory(); }, []); const loadHistory = async () => { try { setLoadingHistory(true); const response = await authFetch('/api/legal/counterparties'); if (response.ok) { const data = await response.json(); setCheckedCounterparties(data); } } catch (error) { console.error('Error loading history:', error); } finally { setLoadingHistory(false); } }; const handleCheck = async () => { if (!inn.trim()) { setError('Введите ИНН организации'); return; } setLoading(true); setError(null); setCheckResult(null); try { const response = await authFetch('/api/legal/check-counterparty', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ inn: inn.trim() }) }); if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.error || 'Ошибка при проверке контрагента'); } const result = await response.json(); setCheckResult(result); // Обновляем историю проверок await loadHistory(); } catch (err) { console.error('Error checking counterparty:', err); setError(err instanceof Error ? err.message : 'Ошибка при проверке контрагента'); } finally { setLoading(false); } }; const handleKeyPress = (e: React.KeyboardEvent) => { if (e.key === 'Enter') { handleCheck(); } }; return (
{/* Search Tool */}

Проверка контрагента

Автоматическая сверка по базам ФНС через DaData API.

{ setInn(e.target.value.replace(/\D/g, '')); setError(null); }} onKeyPress={handleKeyPress} className="flex-1 px-5 py-3 bg-white/10 border border-white/20 rounded-2xl text-sm outline-none focus:ring-2 focus:ring-primary-500 transition-all placeholder:text-slate-500" maxLength={12} />
{error && (
{error}
)}
{/* Check Result */} {checkResult && (
{checkResult.riskLevel === 'high' ? : checkResult.riskLevel === 'medium' ? : }

{checkResult.name}

ИНН: {checkResult.inn} {checkResult.kpp && ` • КПП: ${checkResult.kpp}`} {checkResult.ogrn && ` • ОГРН: ${checkResult.ogrn}`}

{/* Risk Level */}
Уровень риска: {checkResult.riskLevel === 'high' ? 'Высокий риск' : checkResult.riskLevel === 'medium' ? 'Средний риск' : 'Благонадежен'}
{checkResult.riskReasons.length > 0 && (
    {checkResult.riskReasons.map((reason, idx) => (
  • {reason}
  • ))}
)}
{/* Status */}

Статус

{checkResult.status === 'ACTIVE' ? 'Действующая' : checkResult.status === 'LIQUIDATED' ? 'Ликвидирована' : checkResult.status === 'LIQUIDATING' ? 'Ликвидируется' : checkResult.status === 'BANKRUPT' ? 'Банкрот' : checkResult.status === 'REORGANIZING' ? 'Реорганизуется' : checkResult.status}

{checkResult.registrationDate && (

Дата регистрации

{new Date(checkResult.registrationDate).toLocaleDateString('ru-RU')}

)}
{/* Address */} {checkResult.address && (

Адрес

{checkResult.address}

)} {/* Finance */} {checkResult.finance && (

Финансовые показатели

{checkResult.finance.revenue && (

Выручка ({checkResult.finance.year})

{checkResult.finance.revenue.toLocaleString('ru-RU')} ₽

)} {checkResult.finance.income && (

Доходы ({checkResult.finance.year})

{checkResult.finance.income.toLocaleString('ru-RU')} ₽

)} {checkResult.finance.debt && checkResult.finance.debt > 0 && (

Недоимки

{checkResult.finance.debt.toLocaleString('ru-RU')} ₽

)} {checkResult.finance.penalty && checkResult.finance.penalty > 0 && (

Штрафы

{checkResult.finance.penalty.toLocaleString('ru-RU')} ₽

)}
)} {/* Management */} {checkResult.management && (

Руководитель

{checkResult.management.name} {checkResult.management.post && ` • ${checkResult.management.post}`}

)} {/* OKVED */} {checkResult.okved && (

Основной ОКВЭД

{checkResult.okved} {checkResult.okveds?.find(o => o.main)?.name || ''}

)} {/* Capital */} {checkResult.capital != null && checkResult.capital.value != null && (

Уставный капитал

{checkResult.capital.value.toLocaleString('ru-RU')} ₽ {checkResult.capital.type && ({checkResult.capital.type})}

)} {/* SMB */} {checkResult.smb?.category && (

Категория МСП

{checkResult.smb.category === 'MICRO' ? 'Микропредприятие' : checkResult.smb.category === 'SMALL' ? 'Малое' : checkResult.smb.category === 'MEDIUM' ? 'Среднее' : checkResult.smb.category} {checkResult.smb.issueDate && ( (реестр с {new Date(checkResult.smb.issueDate).toLocaleDateString('ru-RU')}) )}

)} {/* Licenses */} {checkResult.licenses && checkResult.licenses.length > 0 && (

Лицензии

    {checkResult.licenses.map((lic, idx) => { const validTo = lic.validTo ? new Date(lic.validTo).getTime() : null; const expired = validTo != null && validTo < Date.now(); return (
  • {lic.number && {lic.number}} {lic.validTo && ( {expired ? 'истекла' : 'до'} {new Date(lic.validTo).toLocaleDateString('ru-RU')} )} {lic.activities?.length ? ` — ${lic.activities.join(', ')}` : ''}
  • ); })}
)} {/* Management disqualified */} {checkResult.managementDisqualified && (

Руководитель дисквалифицирован

Директор не имеет права заключать сделки

)} {/* Invalidity details */} {(checkResult.addressInvalidity || (checkResult.foundersInvalidity && checkResult.foundersInvalidity.length > 0) || (checkResult.managersInvalidity && checkResult.managersInvalidity.length > 0)) && (

Недостоверные сведения

    {checkResult.addressInvalidity &&
  • • Адрес признан недостоверным (ФНС)
  • } {checkResult.foundersInvalidity?.length ?
  • • Сведения об учредителях недостоверны
  • : null} {checkResult.managersInvalidity?.length ?
  • • Сведения о руководителе недостоверны
  • : null}
)}
)} {/* Check History */}

История проверок

{loadingHistory ? (
) : checkedCounterparties.length === 0 ? (

История проверок пуста

Проверьте контрагента, чтобы добавить запись в историю

) : ( checkedCounterparties.map(cp => { const isHighRisk = cp.riskLevel === 'high'; const isMediumRisk = cp.riskLevel === 'medium'; return (
{isHighRisk ? : isMediumRisk ? : }

{cp.name}

ИНН: {cp.inn} • Проверен: {cp.checkedDate ? new Date(cp.checkedDate).toLocaleDateString('ru-RU') : 'Не указано'}

{isHighRisk ? 'Высокий риск' : isMediumRisk ? 'Средний риск' : 'Благонадежен'}

{ try { const response = await authFetch(`/api/legal/counterparties/${cp.id}`); if (response.ok) { const report = await response.json(); setSelectedReport(report); setShowReportModal(true); } } catch (error) { console.error('Error loading report:', error); } }} >
); }))}

Система автоматически блокирует создание договоров с контрагентами, имеющими статус «Высокий риск» до ручного подтверждения Директором.

{/* Report Modal */} {showReportModal && selectedReport && ( { setShowReportModal(false); setSelectedReport(null); }} /> )}
); }; // Report Modal Component interface ReportModalProps { report: any; onClose: () => void; } const ReportModal: React.FC = ({ report, onClose }) => { return (

Детальный отчет о проверке

{/* Header Info */}

{report.name}

ИНН

{report.inn}

{report.kpp && (

КПП

{report.kpp}

)} {report.ogrn && (

ОГРН

{report.ogrn}

)}

Дата проверки

{new Date(report.checkedDate).toLocaleString('ru-RU')}

{/* Risk Level */}
Уровень риска: {report.riskLevel === 'high' ? 'Высокий риск' : report.riskLevel === 'medium' ? 'Средний риск' : 'Благонадежен'}
{report.riskReasons && report.riskReasons.length > 0 && (
    {report.riskReasons.map((reason: string, idx: number) => (
  • {reason}
  • ))}
)}
{/* Status and Dates */}

Статус

{report.status === 'ACTIVE' ? 'Действующая' : report.status === 'LIQUIDATED' ? 'Ликвидирована' : report.status === 'LIQUIDATING' ? 'Ликвидируется' : report.status === 'BANKRUPT' ? 'Банкрот' : report.status === 'REORGANIZING' ? 'Реорганизуется' : report.status}

{report.registrationDate && (

Дата регистрации

{new Date(report.registrationDate).toLocaleDateString('ru-RU')}

)} {report.liquidationDate && (

Дата ликвидации

{new Date(report.liquidationDate).toLocaleDateString('ru-RU')}

)}
{/* Address */} {report.address && (

Адрес

{report.address}

)} {/* Management */} {report.managementName && (

Руководитель

{report.managementName} {report.managementPost && ` • ${report.managementPost}`}

)} {/* OKVED */} {report.okved && (

Основной ОКВЭД

{report.okved} {report.okveds?.find((o: any) => o.main)?.name || ''}

)} {/* Finance */} {report.finance && (

Финансовые показатели

{report.finance.revenue !== undefined && report.finance.revenue !== null && (

Выручка ({report.finance.year})

{report.finance.revenue.toLocaleString('ru-RU')} ₽

)} {report.finance.income !== undefined && report.finance.income !== null && (

Доходы ({report.finance.year})

{report.finance.income.toLocaleString('ru-RU')} ₽

)} {report.finance.expense !== undefined && report.finance.expense !== null && (

Расходы ({report.finance.year})

{report.finance.expense.toLocaleString('ru-RU')} ₽

)} {report.finance.debt !== undefined && report.finance.debt !== null && report.finance.debt > 0 && (

Недоимки

{report.finance.debt.toLocaleString('ru-RU')} ₽

)} {report.finance.penalty !== undefined && report.finance.penalty !== null && report.finance.penalty > 0 && (

Штрафы

{report.finance.penalty.toLocaleString('ru-RU')} ₽

)} {report.finance.taxSystem && (

Система налогообложения

{report.finance.taxSystem}

)}
)} {/* Authorities */} {report.authorities && (

Государственные органы

{report.authorities.ftsRegistration && (

ИФНС регистрации

{report.authorities.ftsRegistration.name}

{report.authorities.ftsRegistration.address && (

{report.authorities.ftsRegistration.address}

)}
)} {report.authorities.ftsReport && (

ИФНС отчётности

{report.authorities.ftsReport.name}

)}
)} {/* Phones and Emails */} {(report.phones?.length > 0 || report.emails?.length > 0) && (

Контакты

{report.phones?.map((phone: any, idx: number) => (
{phone.value || phone}
))} {report.emails?.map((email: any, idx: number) => (
{email.value || email}
))}
)} {/* Employee Count */} {report.employeeCount && (

Среднесписочная численность

{report.employeeCount} человек

)} {/* Capital */} {report.capital != null && report.capital.value != null && (

Уставный капитал

{report.capital.value.toLocaleString('ru-RU')} ₽ {report.capital.type && ({report.capital.type})}

)} {/* SMB */} {report.smb?.category && (

Категория МСП

{report.smb.category === 'MICRO' ? 'Микропредприятие' : report.smb.category === 'SMALL' ? 'Малое' : report.smb.category === 'MEDIUM' ? 'Среднее' : report.smb.category} {report.smb.issueDate && ( (реестр с {new Date(report.smb.issueDate).toLocaleDateString('ru-RU')}) )}

)} {/* Licenses */} {report.licenses && report.licenses.length > 0 && (

Лицензии

    {report.licenses.map((lic: { number?: string; validTo?: number; validFrom?: number; activities?: string[] }, idx: number) => { const validTo = lic.validTo ? new Date(lic.validTo).getTime() : null; const expired = validTo != null && validTo < Date.now(); return (
  • {lic.number && {lic.number}} {lic.validFrom && ( с {new Date(lic.validFrom).toLocaleDateString('ru-RU')} )} {lic.validTo && ( {expired ? 'истекла' : 'до'} {new Date(lic.validTo).toLocaleDateString('ru-RU')} )} {lic.activities?.length ? (

    {lic.activities.join(', ')}

    ) : null}
  • ); })}
)} {/* Management disqualified */} {report.managementDisqualified && (

Руководитель дисквалифицирован

Директор не имеет права заключать сделки

)} {/* Invalidity details */} {(report.addressInvalidity || (report.foundersInvalidity && report.foundersInvalidity.length > 0) || (report.managersInvalidity && report.managersInvalidity.length > 0)) && (

Недостоверные сведения

    {report.addressInvalidity &&
  • • Адрес признан недостоверным (ФНС)
  • } {report.foundersInvalidity?.length ?
  • • Сведения об учредителях недостоверны
  • : null} {report.managersInvalidity?.length ?
  • • Сведения о руководителе недостоверны
  • : null}
)} {/* Notes */} {report.notes && (

Примечания

{report.notes}

)}
); };