Files
Investidor-V2/resources/js/components/simulation-irpc-economic-inclusion.tsx
T
2026-11-10 13:54:06 +02:00

151 lines
5.6 KiB
TypeScript

import { useState } from 'react';
import { annualBook } from '@/lib/irpc-annual-settlement';
import type { NormalBook } from '@/lib/irpc-normal';
import {
prepareEconomicInclusion,
calculateEconomicInclusions,
economicInclusionMoney,
} from '@/lib/irpc-normal-economic';
export function SimulationIrpcEconomicInclusion({
draft,
book,
save,
}: {
draft: Record<string, unknown>;
book: NormalBook;
save: (b: NormalBook) => void;
}) {
const [selected, setSelected] = useState('');
const [profit, setProfit] = useState('');
const [credit, setCredit] = useState('');
const [reference, setReference] = useState('');
const [error, setError] = useState('');
const [preview, setPreview] = useState<{
fingerprint: string;
book: NormalBook;
net: string;
} | null>(null);
const sources = annualBook(draft)?.economicCredits?.rows ?? [];
if (!sources.length) return null;
const fingerprint = JSON.stringify([
book,
sources,
selected,
profit,
credit,
reference,
]);
return (
<section
className="space-y-3 rounded border p-3"
aria-label="Incluir ou corrigir lucros e crédito económico em L6"
>
<h3 className="font-semibold">
Incluir ou corrigir lucros e crédito económico em L6
</h3>
<p>
Escolha a origem preparada em L8. Indique os montantes já
considerados na contabilidade e noutros ajustamentos, antes
deste mapa; zero deve ser indicado expressamente. A prévia
propõe apenas a diferença e conserva o resultado anterior.
Depois de confirmar, calcule e guarde L6 pelo percurso
existente; L8 exige nova conferência da colecta. Valores
derivados mantêm as fracções exactas, sem arredondamento fiscal
presumido.
</p>
<label className="block">
Origem dos lucros
<select
value={selected}
onChange={(e) => setSelected(e.target.value)}
>
<option value="">Escolha a origem</option>
{sources.map((r) => (
<option key={r.id} value={r.id}>
{r.distributionDocument} — {r.distributionParcel}
</option>
))}
</select>
</label>
<label className="block">
Rendimentos já considerados — MZN (incluindo eventual mais-valia
da partilha)
<input
value={profit}
onChange={(e) => setProfit(e.target.value)}
/>
</label>
<label className="block">
Crédito nominal já acrescido — MZN
<input
value={credit}
onChange={(e) => setCredit(e.target.value)}
/>
</label>
<label className="block">
Suporte da reconciliação
<textarea
value={reference}
onChange={(e) => setReference(e.target.value)}
/>
</label>
{error && <p role="alert">{error}</p>}
<button
type="button"
onClick={() => {
try {
const source = sources.find((r) => r.id === selected);
if (!source)
throw Error('Escolha explicitamente uma origem.');
const next = prepareEconomicInclusion(book, {
source,
profitAlreadyIncluded: profit,
creditAlreadyIncluded: credit,
reference,
});
const model = calculateEconomicInclusions(
next.economicInclusions!,
next.base!.subjectNuit,
next.year,
);
setPreview({
fingerprint,
book: next,
net: economicInclusionMoney(model.net),
});
setError('');
} catch (e) {
setPreview(null);
setError(String(e));
}
}}
>
Pré-visualizar inclusão/correcção
</button>
{preview && preview.fingerprint === fingerprint && (
<div className="space-y-2 rounded border p-3">
<p>
Efeito total deste mapa no lucro tributável:{' '}
{preview.net} MZN. Substitui as parcelas da mesma
origem, sem as acumular.
</p>
<button
type="button"
onClick={() => {
if (preview.fingerprint !== fingerprint) return;
save(preview.book);
setPreview(null);
}}
>
Confirmar preparação em L6
</button>
<button type="button" onClick={() => setPreview(null)}>
Cancelar prévia
</button>
</div>
)}
</section>
);
}