184 lines
7.8 KiB
TypeScript
184 lines
7.8 KiB
TypeScript
import { ispcEligibilityBook } from '@/lib/ispc-eligibility';
|
||
import {
|
||
ispcWithholdingBook,
|
||
saveIspcWithholdingBook,
|
||
recordIspcWithholding,
|
||
ispcWithholdingReportRows,
|
||
type IspcWithholdingInput,
|
||
} from '@/lib/ispc-withholding';
|
||
export function SimulationIspcWithholding({
|
||
draft,
|
||
onChange,
|
||
}: {
|
||
draft: Record<string, unknown>;
|
||
onChange: (field: string, value: string) => void;
|
||
}) {
|
||
if (draft.fiscal_component !== 'ispc') return null;
|
||
try {
|
||
if (ispcEligibilityBook(draft).input.mode === 'occasional')
|
||
return (
|
||
<p>
|
||
Retenções do adquirente:entradas preservadas. Neste percurso
|
||
de vendedor ocasional,registe a retenção recebida no quadro
|
||
próprio abaixo.
|
||
</p>
|
||
);
|
||
} catch {
|
||
/* Existing recovery error stays explicit. */
|
||
}
|
||
try {
|
||
const b = ispcWithholdingBook(draft),
|
||
i = b.input,
|
||
change = (p: Partial<IspcWithholdingInput>) =>
|
||
onChange(
|
||
'modelo_a_snapshot',
|
||
saveIspcWithholdingBook(draft, {
|
||
...b,
|
||
input: { ...i, ...p },
|
||
}),
|
||
);
|
||
return (
|
||
<section
|
||
aria-label="Retenções ISPC"
|
||
className="space-y-3 rounded border p-4"
|
||
>
|
||
<h4>ISPC — retenção em aquisições ocasionais</h4>
|
||
<label className="block">
|
||
Existem aquisições abrangidas pelo artigo 12(3–4)?
|
||
<select
|
||
value={i.applicable}
|
||
onChange={(e) =>
|
||
change({
|
||
applicable: e.target
|
||
.value as IspcWithholdingInput['applicable'],
|
||
})
|
||
}
|
||
>
|
||
<option value="">Por esclarecer</option>
|
||
<option value="no">Não</option>
|
||
<option value="yes">Sim — conferir condições</option>
|
||
</select>
|
||
</label>
|
||
{i.applicable === 'yes' && (
|
||
<>
|
||
<p>
|
||
Registe apenas aquisições do mesmo trimestre. O
|
||
acumulado anterior cobre todas as aquisições desta
|
||
via no ano e evita reutilizar o limite por
|
||
fornecedor ou oportunidade.
|
||
</p>
|
||
{(
|
||
[
|
||
'quarter',
|
||
'base',
|
||
'priorAnnualPurchases',
|
||
'reference',
|
||
] as const
|
||
).map((k) => (
|
||
<label className="block" key={k}>
|
||
{
|
||
{
|
||
quarter: 'Trimestre de 2026',
|
||
base: 'Base de aquisições deste trimestre em MZN',
|
||
priorAnnualPurchases:
|
||
'Aquisições globais anteriores de 2026 em MZN',
|
||
reference:
|
||
'Suporte das aquisições e condições',
|
||
}[k]
|
||
}
|
||
<input
|
||
className="block rounded border p-2"
|
||
value={i[k]}
|
||
onChange={(e) =>
|
||
change({ [k]: e.target.value })
|
||
}
|
||
/>
|
||
</label>
|
||
))}
|
||
{(
|
||
[
|
||
'naturalOccasional',
|
||
'unregistered',
|
||
'related',
|
||
] as const
|
||
).map((k) => (
|
||
<label className="block" key={k}>
|
||
{
|
||
{
|
||
naturalOccasional:
|
||
'Fornecedor pessoa singular ocasional abrangido por 3(3–4)',
|
||
unregistered:
|
||
'Fornecedor não inscrito para tributação',
|
||
related:
|
||
'Bens relacionados com a actividade do adquirente',
|
||
}[k]
|
||
}
|
||
<select
|
||
value={i[k]}
|
||
onChange={(e) =>
|
||
change({ [k]: e.target.value })
|
||
}
|
||
>
|
||
<option value="">Por esclarecer</option>
|
||
<option value="yes">Sim</option>
|
||
<option value="no">Não</option>
|
||
</select>
|
||
</label>
|
||
))}
|
||
<label className="block">
|
||
Actividade da operação ocasional
|
||
<select
|
||
value={i.activity}
|
||
onChange={(e) =>
|
||
change({
|
||
activity: e.target
|
||
.value as IspcWithholdingInput['activity'],
|
||
})
|
||
}
|
||
>
|
||
{[
|
||
['', 'Por identificar'],
|
||
['forestry', 'Silvícola'],
|
||
['fishery', 'Pesqueira'],
|
||
['livestock', 'Pecuária'],
|
||
['agriculture', 'Agrícola'],
|
||
['poultry', 'Avícola'],
|
||
['beekeeping', 'Apícola'],
|
||
['other', 'Outra'],
|
||
].map(([v, l]) => (
|
||
<option key={v} value={v}>
|
||
{l}
|
||
</option>
|
||
))}
|
||
</select>
|
||
</label>
|
||
</>
|
||
)}
|
||
<button
|
||
type="button"
|
||
className="rounded border p-2"
|
||
onClick={() =>
|
||
onChange(
|
||
'modelo_a_snapshot',
|
||
saveIspcWithholdingBook(
|
||
draft,
|
||
recordIspcWithholding(draft, b),
|
||
),
|
||
)
|
||
}
|
||
>
|
||
Conferir e guardar retenção ISPC
|
||
</button>
|
||
{ispcWithholdingReportRows(draft).map((r, n) => (
|
||
<p key={n}>
|
||
<strong>{r[1]}:</strong> {r[2]}
|
||
<small className="block">{r[3]}</small>
|
||
</p>
|
||
))}
|
||
</section>
|
||
);
|
||
} catch (e) {
|
||
return <p role="alert">{String(e)}</p>;
|
||
}
|
||
}
|