170 lines
6.2 KiB
TypeScript
170 lines
6.2 KiB
TypeScript
import {
|
|
newPpcObligation,
|
|
calculatePpcObligation,
|
|
ppcObligationSource,
|
|
type PpcObligation,
|
|
} from '@/lib/irpc-ppc-obligation';
|
|
import { fractionPresentation } from '@/lib/fiscal-rational';
|
|
import type { AnnualBook } from '@/lib/irpc-annual-settlement';
|
|
export function SimulationIrpcPpcObligation({
|
|
book,
|
|
onChange,
|
|
}: {
|
|
book: AnnualBook;
|
|
onChange: (value: PpcObligation) => void;
|
|
}) {
|
|
const p = book.ppcObligation;
|
|
if (!p)
|
|
return (
|
|
<section className="rounded border p-3">
|
|
<h5>Estimativa PPC</h5>
|
|
<p>
|
|
Preparar a obrigação e os meses previstos não regista
|
|
pagamentos nem cria deduções na liquidação.
|
|
</p>
|
|
<button
|
|
type="button"
|
|
onClick={() =>
|
|
onChange(newPpcObligation(book.subjectNuit, book.year))
|
|
}
|
|
>
|
|
Simular PPC
|
|
</button>
|
|
</section>
|
|
);
|
|
const m = calculatePpcObligation(
|
|
p,
|
|
book.subjectNuit,
|
|
book.year,
|
|
book.assessment,
|
|
);
|
|
const patch = (changes: Partial<PpcObligation>) =>
|
|
onChange({ ...p, ...changes });
|
|
const field = (
|
|
key:
|
|
| 'subjectNuit'
|
|
| 'year'
|
|
| 'previousYear'
|
|
| 'previousTax'
|
|
| 'previousWithholdings'
|
|
| 'assessmentReference'
|
|
| 'withholdingReference',
|
|
label: string,
|
|
) => (
|
|
<label className="block">
|
|
{label}
|
|
<input
|
|
aria-label={label}
|
|
value={p[key]}
|
|
onChange={(e) => patch({ [key]: e.target.value })}
|
|
/>
|
|
</label>
|
|
);
|
|
return (
|
|
<section
|
|
aria-label="Preparação da estimativa PPC"
|
|
className="rounded border p-3"
|
|
>
|
|
<h5>Estimativa PPC — exercício anterior</h5>
|
|
<p>
|
|
Reutiliza o titular e exercício ao iniciar. Complete a
|
|
liquidação anterior e as retenções documentadas; campos vazios
|
|
não equivalem a zero.
|
|
</p>
|
|
<label className="block">
|
|
Enquadramento PPC
|
|
<select
|
|
aria-label="Enquadramento PPC"
|
|
value={p.scope}
|
|
onChange={(e) =>
|
|
patch({
|
|
scope: e.target.value as PpcObligation['scope'],
|
|
})
|
|
}
|
|
>
|
|
<option value="">Por confirmar</option>
|
|
<option value="ordinary_resident">
|
|
Residente geral — actividade comercial, industrial ou
|
|
agrícola, ano civil
|
|
</option>
|
|
<option value="other">
|
|
Outro enquadramento — cálculo separado
|
|
</option>
|
|
</select>
|
|
</label>
|
|
{p.scope === 'ordinary_resident' && (
|
|
<>
|
|
{field('subjectNuit', 'NUIT — estimativa PPC')}
|
|
{field('year', 'Exercício — estimativa PPC')}
|
|
{field('previousYear', 'Exercício anterior — PPC')}
|
|
<label className="block">
|
|
Exercício anterior civil completo
|
|
<select
|
|
aria-label="Exercício anterior civil completo"
|
|
value={p.previousFullCalendarYear}
|
|
onChange={(e) =>
|
|
patch({
|
|
previousFullCalendarYear: e.target
|
|
.value as PpcObligation['previousFullCalendarYear'],
|
|
})
|
|
}
|
|
>
|
|
<option value="">Por confirmar</option>
|
|
<option value="yes">Sim</option>
|
|
<option value="no">
|
|
Não — anualização/período especial separado
|
|
</option>
|
|
</select>
|
|
</label>
|
|
{field(
|
|
'previousTax',
|
|
'Imposto liquidado anterior21(1) — MZN',
|
|
)}
|
|
{field(
|
|
'assessmentReference',
|
|
'Fonte da liquidação anterior — PPC',
|
|
)}
|
|
{field(
|
|
'previousWithholdings',
|
|
'Retenções na fonte anteriores — MZN',
|
|
)}
|
|
{field(
|
|
'withholdingReference',
|
|
'Fonte das retenções anteriores — PPC',
|
|
)}
|
|
</>
|
|
)}
|
|
{m.pending.length ? (
|
|
<p role="status">{m.pending.join(' ')}</p>
|
|
) : (
|
|
<>
|
|
<p>
|
|
80% antes de arredondar:{' '}
|
|
{fractionPresentation(m.annualBeforeRounding!).decimal}{' '}
|
|
MZN. Total das três prestações arredondadas:{' '}
|
|
{fractionPresentation(m.total!).decimal} MZN.
|
|
</p>
|
|
<ul>
|
|
{m.schedule.map((s) => (
|
|
<li key={s.month}>
|
|
{s.month}:{' '}
|
|
{fractionPresentation(s.amount).decimal} MZN
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</>
|
|
)}
|
|
<p>
|
|
Guardar o rascunho conserva esta preparação; calcular o fecho
|
|
anual inclui-a no relatório. Só comprovativos efectivos podem
|
|
alimentar as deduções PPC abaixo. Não executa pagamento,
|
|
dispensa, guia ou juros.
|
|
</p>
|
|
<details>
|
|
<summary>Fonte e limites</summary>
|
|
<p>{ppcObligationSource}</p>
|
|
</details>
|
|
</section>
|
|
);
|
|
}
|