104 lines
4.6 KiB
TypeScript
104 lines
4.6 KiB
TypeScript
import { isApiSimulationResultSnapshotV1 } from './simulation-contract.ts';
|
|
import { modeloAComponentRows } from './iva-modelo-a.ts';
|
|
|
|
export function fiscalQaRows(value: unknown): Array<[string, string]> {
|
|
if (!isApiSimulationResultSnapshotV1(value)) return [];
|
|
const snapshot = value as unknown as Record<string, unknown>;
|
|
if (
|
|
!['fiscal_rule_qa_preview', 'fiscal_rule_published'].includes(
|
|
String(snapshot.scenario_kind),
|
|
)
|
|
)
|
|
return [];
|
|
const published = snapshot.scenario_kind === 'fiscal_rule_published';
|
|
const provenance = snapshot.fiscal_provenance as
|
|
| Record<string, unknown>
|
|
| undefined;
|
|
const rule = provenance?.rule as Record<string, unknown> | undefined;
|
|
const source = rule?.source as Record<string, unknown> | undefined;
|
|
const parameters = rule?.parameters as
|
|
| Record<string, Record<string, unknown>>
|
|
| undefined;
|
|
const intermediate = snapshot.intermediate as Record<
|
|
string,
|
|
unknown
|
|
> | null;
|
|
const text = (item: unknown) =>
|
|
typeof item === 'string' || typeof item === 'number'
|
|
? String(item)
|
|
: 'não disponível';
|
|
const monthly = snapshot.monthly_projection as
|
|
| { rows?: Array<Record<string, unknown>>; cash_treatment?: string }
|
|
| undefined;
|
|
return [
|
|
...modeloAComponentRows(snapshot),
|
|
...(monthly?.rows
|
|
? ([
|
|
[
|
|
'Projecção mensal',
|
|
'Vendas tributáveis sem IVA → taxa aplicada → IVA calculado → total com IVA; não é apuramento final',
|
|
],
|
|
...monthly.rows.map((row) => [
|
|
`Mês ${text(row.date)}`,
|
|
`Vendas declaradas: ${text(row.sales_declared)}; base líquida: ${text(row.net_sales)}; taxa: ${row.rate == null ? 'não aplicada' : `${text(row.rate)}%`}; IVA: ${text(row.vat)}; total com IVA: ${text(row.gross_sales)}; ${row.status === 'calculated' ? 'calculado' : row.status === 'missing_sales' ? 'sem informação de vendas' : row.status === 'unsupported_basis' ? 'base líquida não determinada' : 'enquadramento ou regra indeterminados'}`,
|
|
]),
|
|
[
|
|
'Tratamento na tesouraria',
|
|
monthly.cash_treatment ??
|
|
'IVA separado; não é custo nem imposto a pagar',
|
|
],
|
|
] as Array<[string, string]>)
|
|
: []),
|
|
[
|
|
'Relatório',
|
|
published
|
|
? 'IVA pela versão publicada; ver enquadramento abaixo'
|
|
: 'Pré-visualização fiscal QA de rascunho — sem activação',
|
|
],
|
|
[
|
|
'IVA calculado (exacto; não é saldo a pagar)',
|
|
value.result.value ?? 'Indeterminado',
|
|
],
|
|
['Explicação', value.result.explanation],
|
|
['Base tributável declarada', text(snapshot.base)],
|
|
['Taxa cadastrada (%)', text(parameters?.IVA_GENERAL_RATE?.value)],
|
|
['Moeda explícita', text(value.context.currency)],
|
|
[
|
|
monthly
|
|
? 'Início da projecção mensal'
|
|
: 'Data de exigibilidade declarada',
|
|
value.context.reference_date,
|
|
],
|
|
[
|
|
'Enquadramento',
|
|
provenance?.scope_status === 'undetermined'
|
|
? 'Indeterminado: falta declaração do enquadramento'
|
|
: 'Declarado pelo utilizador; não validado juridicamente',
|
|
],
|
|
[
|
|
'Regra / versão / estado',
|
|
`${text(rule?.rule_code)} / ${text(rule?.rule_version)} / ${published ? 'publicada no momento da admissão' : 'rascunho'}`,
|
|
],
|
|
[
|
|
'Vigência cadastrada',
|
|
`${text(rule?.valid_from)} até ${rule?.valid_until === null ? 'sem termo indicado' : text(rule?.valid_until)}`,
|
|
],
|
|
[
|
|
'Fonte da taxa',
|
|
`${text(source?.diploma)} — ${text(source?.article)}`,
|
|
],
|
|
['Hash do exemplar da taxa', text(rule?.source_sha256)],
|
|
['Representação racional exacta', text(intermediate?.result)],
|
|
[
|
|
'Arredondamento',
|
|
'Não aplicado. Valor calculado preservado sem truncar ou arredondar; apresentação monetária separada.',
|
|
],
|
|
[
|
|
'Limitações',
|
|
published
|
|
? 'Cobertura de 2026; operação interna geral em MZN; sem excepções, deduções, declaração ou saldo a pagar.'
|
|
: 'Regra não publicada; cobertura demonstrada em 2026; sem deduções, declaração ou saldo a pagar.',
|
|
],
|
|
];
|
|
}
|