import { useEffect, useState } from 'react'; import { fiscalComponentCodes } from '@/lib/simulation-contract'; import { ivaIssueText, type IvaDiagnostic, type IvaIssue, } from '@/lib/iva-diagnostics'; type Parameter = { parameter_code: string; status: string; value: string | null; unit?: string; scope_key?: string; rule_code?: string; rule_version?: number; validity?: { start: string; end: string | null }; source?: { title: string; diploma: string | null; article: string | null; url: string | null; }; }; const labels: Record = { indeterminate_missing: 'Não existe parâmetro aprovado para este âmbito e período.', indeterminate_context: 'As condições publicadas não correspondem às respostas indicadas.', indeterminate_scope: 'O âmbito da regra não está suficientemente definido.', indeterminate_overlap: 'Há regras sobrepostas; é necessária revisão.', indeterminate_period_change: 'A vigência muda dentro do período seleccionado.', indeterminate_invalid: 'O parâmetro publicado não passou a validação de formato.', }; const apiComponents: Record = { irpc: 'IRPC', iva: 'IVA', ispc: 'ISPC', irps: 'IRPS', inss: 'INSS', withholding: 'RETENCOES', retenções: 'RETENCOES', }; function getXsrfToken(): string { return decodeURIComponent( document.cookie .split('; ') .find((cookie) => cookie.startsWith('XSRF-TOKEN=')) ?.slice(11) ?? '', ); } export function SimulationFiscalStatus({ salaryView, scenarioMode, component, periodStart, periodEnd, context, onDiagnostics, onCorrect, }: { salaryView?: string; scenarioMode?: string; component?: string; periodStart?: string; periodEnd?: string; context?: Record; onDiagnostics?: (issues: IvaIssue[]) => void; onCorrect?: (field: string) => void; }) { const [parameters, setParameters] = useState([]); const [diagnostics, setDiagnostics] = useState([]); const [requestState, setRequestState] = useState('idle'); const [retry, setRetry] = useState(0); useEffect(() => { const apiComponent = component ? apiComponents[component.toLowerCase()] : undefined; if ( scenarioMode !== 'approved_parameters' || !apiComponent || !periodStart || !periodEnd ) { setParameters([]); setDiagnostics([]); onDiagnostics?.([]); setRequestState('idle'); return; } const abort = new AbortController(); setDiagnostics([]); onDiagnostics?.([]); setRequestState('loading'); void fetch('/api/v1/tax-parameters/resolve', { method: 'POST', credentials: 'same-origin', signal: abort.signal, headers: { 'Content-Type': 'application/json', Accept: 'application/json', 'X-XSRF-TOKEN': getXsrfToken(), }, body: JSON.stringify({ component: apiComponent, period_start: periodStart, period_end: periodEnd, context: context ?? {}, }), }) .then(async (response) => { if (!response.ok) throw new Error('lookup_failed'); const payload = (await response.json()) as { parameters?: Parameter[]; diagnostics?: IvaDiagnostic[]; }; if (abort.signal.aborted) return; setParameters( Array.isArray(payload.parameters) ? payload.parameters : [], ); const details = Array.isArray(payload.diagnostics) ? payload.diagnostics : []; setDiagnostics(details); onDiagnostics?.(details.flatMap((detail) => detail.issues)); setRequestState('done'); }) .catch((error: unknown) => { if (abort.signal.aborted) return; if ( error instanceof DOMException && error.name === 'AbortError' ) return; setParameters([]); setRequestState('error'); }); return () => abort.abort(); }, [ scenarioMode, component, periodStart, periodEnd, JSON.stringify(context ?? {}), retry, ]); const salaryViewMessages: Record = { monthly_net_estimate: 'Estimativa líquida mensal; retenção mensal e apuramento anual são resultados distintos.', monthly_withholding: 'Retenção mensal não representa, por si só, o apuramento anual nem o cumprimento integral das obrigações fiscais.', annual_assessment: 'Apuramento anual; retenções mensais não o substituem.', }; return (

Componentes fiscais e contributivas

A consulta identifica parâmetros publicados e as respectivas fontes. Não executa fórmulas nem determina imposto devido ou elegibilidade fiscal.

{scenarioMode === 'approved_parameters' && (

{requestState === 'loading' ? 'A consultar parâmetros aprovados para o período e âmbito indicados…' : requestState === 'error' ? 'Falha na consulta do sistema: não foi possível obter os parâmetros. O problema não é atribuído às respostas; estas foram preservadas. Tente novamente.' : !periodStart || !periodEnd ? 'Indique um período exacto. Para periodicidade mensal ou trimestral, seleccione o mês ou trimestre.' : `Período consultado: ${periodStart} a ${periodEnd}.`}

)} {requestState === 'error' && scenarioMode === 'approved_parameters' && ( )} {scenarioMode === 'custom_planning' && (

Modo de planeamento separado: pressupostos do utilizador, não taxas legais confirmadas. Nenhum imposto ou elegibilidade é calculado.

)} {salaryView && salaryViewMessages[salaryView] && (

{salaryViewMessages[salaryView]}

)} {diagnostics.length > 0 && (

IVA — taxa geral: condições não satisfeitas

Não foi possível resolver este parâmetro. As respostas foram preservadas; esta consulta não executa o cálculo do imposto.

{diagnostics.map((detail, index) => (
Ver fundamento

IVA — taxa geral · versão{' '} {detail.rule_version}. Vigência:{' '} {detail.validity.start} a{' '} {detail.validity.end ?? 'sem data final indicada'} .

{detail.source.title} —{' '} {detail.source.diploma},{' '} {detail.source.article}

{detail.source.url?.startsWith('https://') && ( Consultar fonte )}
))}
)}
    {fiscalComponentCodes.map((code) => { const selected = code === (component === 'withholding' ? 'RETENCOES' : component?.toUpperCase()); return (
  • {code === 'RETENCOES' ? 'Retenções' : code} {!selected || scenarioMode !== 'approved_parameters' ? (

    Sem cálculo fiscal

    ) : requestState !== 'done' ? (

    Indeterminado — sem cálculo

    ) : parameters.length === 0 ? (

    {code === 'IVA' ? ( 'Indeterminado — não existe uma versão elegível visível nesta consulta. Consulte o diagnóstico do período acima, quando disponível. Sem esse diagnóstico, não é possível distinguir ausência de cobertura de indisponibilidade da regra ou da fonte; não se atribui o problema às suas respostas.' ) : ( <> Indeterminado — nenhum parâmetro publicado aplicável. Faltam parâmetros aprovados para {code}, no período {periodStart} a {periodEnd}{' '} e no âmbito indicado. A consulta não identifica um conjunto obrigatório de parâmetros; não é possível determinar o imposto nem substituir as lacunas por zero. )}

    ) : (
    {parameters.map((parameter) => (
    {parameter.parameter_code === 'IVA_GENERAL_RATE' ? 'IVA — taxa geral' : parameter.parameter_code} {parameter.status === 'resolved' ? ( <>

    Parâmetro:{' '} {parameter.value}{' '} {parameter.unit}

    Regra{' '} {parameter.parameter_code === 'IVA_GENERAL_RATE' ? 'IVA — taxa geral' : parameter.rule_code}{' '} v {parameter.rule_version} ; âmbito{' '} {parameter.parameter_code === 'IVA_GENERAL_RATE' ? 'operação interna geral sobre base líquida em MZN' : parameter.scope_key}

    Vigência:{' '} { parameter.validity ?.start }{' '} a{' '} {parameter.validity ?.end ?? 'sem data final'}

    Fonte:{' '} { parameter.source ?.title } {parameter.source ?.diploma ? ` — ${parameter.source.diploma}` : ''} {parameter.source ?.article ? `, ${parameter.source.article}` : ''}

    {parameter.source?.url && ( Ver fundamento )} ) : (

    {(parameter.parameter_code === 'IVA_GENERAL_RATE' && diagnostics.length ? 'Consulte acima cada condição e o fundamento da versão.' : labels[ parameter.status ]) ?? 'Indeterminado — não foi possível validar o parâmetro.'}

    )}
    ))}
    )}
  • ); })}
); }