Files
Investidor-V2/resources/js/lib/fiscal-qa-preview.ts
T

69 lines
4.1 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.",
],
];
}