Files
Investidor-V2/resources/js/components/simulation-irpc-pt-cdt.tsx
T
2026-11-10 14:18:47 +02:00

278 lines
14 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import {
newPtMzRoyaltyPreparation,
type InternationalPosition,
type PtMzRoyaltyPreparation,
} from '@/lib/irpc-international-credit';
export function SimulationIrpcPtCdt({
position: p,
patch,
prefix,
}: {
position: InternationalPosition;
patch: (v: Partial<InternationalPosition>) => void;
prefix: string;
}) {
if (!p.treatyMethod || p.treatyMethod === 'documented') return null;
const change = (key: keyof PtMzRoyaltyPreparation, value: string) =>
patch({
treatyPreparation: {
...newPtMzRoyaltyPreparation(),
...p.treatyPreparation,
[key]: value,
},
});
const facts: [keyof PtMzRoyaltyPreparation, string][] = [
['residentMz', 'Beneficiário residente convencional em Moçambique'],
['beneficialOwner', 'Beneficiário efectivo do rendimento'],
[
'payerResidentPt',
'Devedor/sociedade distribuidora residente em Portugal',
],
[
'sourcePortugal',
'Fonte portuguesa, incluindo correspondência de quem suporta o encargo',
],
['noLinkedEstablishment', 'Sem EP/instalação fixa ligada em Portugal'],
];
if (p.treatyMethod !== 'ptMzDividend')
facts.push(['armLength', 'Sem excesso por relações especiais']);
if (p.treatyMethod === 'ptMzRoyalty')
facts.push(
[
'royaltyDefinition',
'Definição convencional de royalties documentada',
],
['nonDigital', 'Caso ordinário não digital'],
);
else
facts.push([
'capitalDefinition',
'Definição convencional de dividendos/juros documentada',
]);
if (p.treatyMethod === 'ptMzInterest')
facts.push([
'governmentInterestExemption',
'Juros abrangidos pela isenção governamental do art.11(3)',
]);
return (
<fieldset className="space-y-2 rounded border p-3">
<legend>Portugal — correspondência CDT</legend>
<p>
Confirme rendimento bruto em MZN, residência convencional,
natureza e período coberto pelos documentos. O limite
convencional do caso qualificado restringe o imposto estrangeiro
elegível; não altera a parcela líquida nacional nem prova
pagamento. O limite manual anterior fica conservado.
</p>
{(
[
['gross', 'Rendimento bruto — MZN'],
['from', 'Início do período documentado — AAAA-MM-DD'],
['to', 'Fim do período documentado — AAAA-MM-DD'],
[
'reference',
'Suporte da residência, contrato e condições convencionais',
],
] as const
).map(([key, label]) => (
<label key={key} className="block">
{label}
<input
aria-label={prefix + label}
value={p.treatyPreparation?.[key] ?? ''}
onChange={(e) => change(key, e.target.value)}
/>
</label>
))}
{p.treatyMethod === 'ptMzInterest' &&
p.treatyPreparation?.governmentInterestExemption === 'yes' && (
<fieldset className="space-y-2 rounded border p-3">
<legend>
Fundamento da isenção dos juros — art.11(3)
</legend>
<label className="block">
Fundamento
<select
aria-label={
prefix +
'Fundamento da isenção governamental'
}
value={
p.treatyPreparation.governmentBasis ??
(p.treatyPreparation.governmentPayer
? 'payer'
: '')
}
onChange={(e) =>
change('governmentBasis', e.target.value)
}
>
<option value="">Escolha o fundamento</option>
<option value="payer">
Devedor público português —11(3)a
</option>
<option value="agreement">
Instituição/organismo e financiamento sob
acordo PT–MZ —11(3)b
</option>
</select>
</label>
{p.treatyPreparation.governmentBasis === 'agreement' ? (
<>
<p>
O beneficiário é o sujeito corrente:{' '}
{p.subjectNuit}. Confirme a
instituição/organismo, o financiamento por
ela concedido e o acordo entre os governos
de Portugal e Moçambique. A isenção não é
inferida pelo nome; outros
beneficiários/regimes conservam
correspondência própria.
</p>
{(
[
[
'institutionRecipient',
'Beneficiário corrente qualificado como instituição/organismo11(3)b',
],
[
'financingGranted',
'Juros resultam de financiamento concedido por esse beneficiário',
],
[
'bilateralAgreement',
'Financiamento no âmbito de acordo concluído entre os governos PT–MZ',
],
] as const
).map(([key, label]) => (
<label key={key} className="block">
{label}
<select
aria-label={prefix + label}
value={
p.treatyPreparation?.[key] ?? ''
}
onChange={(e) =>
change(key, e.target.value)
}
>
<option value="">
Informação em falta
</option>
<option value="yes">
Sim — documentado
</option>
<option value="no">
Não — documentado
</option>
</select>
</label>
))}
{(
[
[
'institutionReference',
'Suporte da qualificação do beneficiário corrente',
],
[
'financingReference',
'Suporte do financiamento e ligação aos juros',
],
[
'agreementReference',
'Acordo PT–MZ e cláusula aplicável a este financiamento',
],
] as const
).map(([key, label]) => (
<label key={key} className="block">
{label}
<input
aria-label={prefix + label}
value={
p.treatyPreparation?.[key] ?? ''
}
onChange={(e) =>
change(key, e.target.value)
}
/>
</label>
))}
</>
) : (
<>
<p>
Qualifique o devedor público português com
suporte próprio. A isenção na fonte não
gera, no portal, reembolso do imposto pago.
</p>
<label className="block">
Devedor dos juros
<select
aria-label={
prefix + 'Devedor público português'
}
value={
p.treatyPreparation
.governmentPayer ?? ''
}
onChange={(e) =>
change(
'governmentPayer',
e.target.value,
)
}
>
<option value="">Por documentar</option>
<option value="state">
Estado português
</option>
<option value="subdivision">
Subdivisão política/administrativa
portuguesa
</option>
<option value="local">
Autarquia portuguesa
</option>
</select>
</label>
<label className="block">
Suporte da qualificação do devedor
<input
aria-label={
prefix +
'Suporte do devedor público'
}
value={
p.treatyPreparation
.governmentPayerReference ?? ''
}
onChange={(e) =>
change(
'governmentPayerReference',
e.target.value,
)
}
/>
</label>
</>
)}
</fieldset>
)}
{facts.map(([key, label]) => (
<label key={key} className="block">
{label}
<select
aria-label={prefix + label}
value={p.treatyPreparation?.[key] ?? ''}
onChange={(e) => change(key, e.target.value)}
>
<option value="">Informação em falta</option>
<option value="yes">Sim — documentado</option>
<option value="no">Não — documentado</option>
</select>
</label>
))}
</fieldset>
);
}