Files
Investidor-V2/resources/js/components/acquisition-allocation.tsx
T

342 lines
16 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 type { Acquisition } from '@/lib/iva-acquisitions';
import { newAcquisitionBC } from '@/lib/iva-acquisition-bc';
import {
newAcquisitionAllocation,
allocationReducedChoices,
adoptAllocationReduced,
acquisitionAllocationDecision,
type AcquisitionAllocation,
} from '@/lib/iva-acquisition-allocation';
export function AcquisitionAllocationEditor({
draft,
row,
onChange,
}: {
draft: Record<string, unknown>;
row: Acquisition;
onChange: (patch: Partial<Acquisition>) => void;
}) {
const d = row.d;
if (!d)
return (
<button
type="button"
onClick={() =>
onChange({
d: {
...newAcquisitionAllocation(row.period),
noExcludedPayments:
row.deductionLink?.noExcludedPayments ?? '',
},
bc: row.bc ?? newAcquisitionBC(),
})
}
>
Preparar afectação parcial e proporções — D (conserva dados e
histórico)
</button>
);
const update = (value: Partial<AcquisitionAllocation>) =>
onChange({ d: { ...d, ...value } });
const fact = (key: string, label: string) => (
<label className="block" key={key}>
{label}
<select
value={d.facts[key] ?? ''}
onChange={(e) =>
update({
facts: {
...d.facts,
[key]: e.target.value as '' | 'yes' | 'no',
},
})
}
>
<option value="">Por indicar</option>
<option value="yes">Sim</option>
<option value="no">Não</option>
</select>
</label>
);
const text = (
key:
| 'numerator'
| 'denominator'
| 'unit'
| 'referenceYear'
| 'scopeRef'
| 'source'
| 'communicationRef'
| 'declarationRef',
label: string,
) => (
<label className="block" key={key}>
{label}
<input
value={d[key]}
onChange={(e) => update({ [key]: e.target.value })}
/>
</label>
);
const decision = acquisitionAllocationDecision(draft, row),
choices = d.method === 'reduced' ? allocationReducedChoices(draft) : [];
return (
<fieldset className="space-y-2 rounded border p-3">
<legend>Afectação parcial e proporções — D</legend>
<p>
Reutiliza documento,montantes,moeda,período e condiçõesB/C.
Escolher afectação real/pro rata identifica esta aquisição como
mista;18(6),como exclusiva ao âmbito de origem. O vínculo
individual deA permanece conservado,sem definir silenciosamente
a afectação mista. A versão anterior não é recalculada.
</p>
<label className="block">
Método de afectação/dedução
<select
value={d.method}
onChange={(e) => {
const method = e.target
.value as AcquisitionAllocation['method'];
onChange({
d: { ...d, method },
...(method
? {
allocation:
method === 'reduced'
? 'taxable_only'
: 'mixed',
}
: {}),
});
}}
>
<option value="">Por identificar</option>
<option value="actual">Afectação real22(2)</option>
<option value="pro_rata">
Pro rata provisório22(1)/(4)/(6)/(7)
</option>
<option value="reduced">
Proporção específica18(6) — origemP096–P099
</option>
</select>
</label>
{text(
'scopeRef',
'Âmbito da aquisição/actividade:entidade,operações,período e critério aplicáveis',
)}
{text(
'source',
'Fonte/documento ou pressuposto expresso das bases e do método',
)}
{fact(
'scopeConfirmed',
'Esta aquisição corresponde ao âmbito e à fonte identificados;sem usar apenas o sector ou a oportunidade',
)}
<label className="block">
Aquisição fora dos pagamentos excluídos15(6)(c)/19(2)
<select
value={d.noExcludedPayments}
onChange={(e) =>
update({
noExcludedPayments: e.target
.value as AcquisitionAllocation['noExcludedPayments'],
})
}
>
<option value="">Por indicar</option>
<option value="yes">Sim</option>
<option value="no">Não</option>
</select>
</label>
{d.method === 'reduced' ? (
<>
<label className="block">
Reutilizar base reduzida existente
<select
value={d.reducedId}
onChange={(e) => {
if (e.target.value)
update(
adoptAllocationReduced(
draft,
d,
e.target.value,
),
);
}}
>
<option value="">
Escolher origem correspondente
</option>
{choices.map((c) => (
<option key={c.id} value={c.id}>
{c.label}
</option>
))}
</select>
</label>
{!choices.length && (
<p>
Não há base reduzida registada nesta oportunidade.
Prepare a origem no percurso existente;sem
percentagem por defeito.
</p>
)}
{!!d.reducedId && (
<button
type="button"
onClick={() =>
update(
adoptAllocationReduced(
draft,
d,
d.reducedId,
),
)
}
>
Adoptar expressamente a origem actual e rever o
âmbito
</button>
)}
<p>
Reutiliza62%,85%,40% ou75% segundo a origem demonstrada.
São proporções de dedução18(6),não taxasIVA. Não volta a
reduzir o montante de aquisição nem duplica o desconto
da base.
</p>
</>
) : (
d.method && (
<>
{fact(
'rightBasis',
'A parte identificada dá direito à dedução18/19,com fundamento na fonte indicada;isenção não implica automaticamente direito',
)}
{text(
'numerator',
d.method === 'actual'
? 'Parte efectivamente afecta a operações com direito — numerador'
: 'Montante anual semIVA das operações com direito18/19 — numerador',
)}
{text(
'denominator',
d.method === 'actual'
? 'Utilização total no mesmo critério/unidade — denominador'
: 'Montante anual semIVA de todas as operações,incluindo fora de campo — denominador',
)}
{d.method === 'actual' ? (
<>
{text(
'unit',
'Unidade e critério de afectação real (mesma base em ambas as parcelas)',
)}
{fact(
'actualScope',
'Repartição corresponde à afectação real desta aquisição/parte,documentada no critério identificado',
)}
{fact(
'communication',
'Comunicação prévia à Direcção Geral de Impostos22(2),conforme a fonte — não é nova aprovação do portal',
)}
{text(
'communicationRef',
'Referência da comunicação prévia22(2)',
)}
{fact(
'conditionsMet',
'Condições especiais concretamente aplicáveis ao método,quando existentes,estão reflectidas na fonte e cumpridas',
)}
</>
) : (
<>
<label className="block">
Base do pro rata provisório
<select
value={d.basis}
onChange={(e) =>
update({
basis: e.target
.value as AcquisitionAllocation['basis'],
})
}
>
<option value="">Por indicar</option>
<option value="prior_year">
Operações do ano anterior22(6)
</option>
<option value="initial_changed">
Estimativa expressa por
início/alteração substancial22(7)
</option>
</select>
</label>
{text(
'referenceYear',
'Ano das bases anuais utilizadas',
)}
{fact(
'annualScope',
'Totais cobrem o âmbito anual do sujeito passivo identificado,sem substituir pelo mês ou apenas por uma oportunidade',
)}
{fact(
'netExclusions',
'Bases semIVA22(4–5):incluem operações fora de campo;excluem vendas de activo usado e imobiliárias/financeiras acessórias',
)}
{d.basis === 'initial_changed' && (
<>
{fact(
'initialChanged',
'Há início de actividade ou alteração substancial que fundamenta a estimativa22(7)',
)}
{text(
'declarationRef',
'Referência da declaração de início/alterações que contém a estimativa',
)}
</>
)}
<label className="block">
Existe imposição concreta de afectação
real22(3) para este âmbito?
<select
value={d.actualRequired}
onChange={(e) =>
update({
actualRequired: e.target
.value as AcquisitionAllocation['actualRequired'],
})
}
>
<option value="">
Nenhuma imposição concreta
identificada neste registo
</option>
<option value="yes">
Sim — usar método correspondente e
fonte
</option>
<option value="no">Não</option>
</select>
</label>
<p>
O quociente é arredondado à centésima
imediatamente superior22(8). Mantêm-se o
quociente original e a proporção
aplicada;fracções monetárias continuam
exactas. O acerto anual22(6) segueE,sem
alterar versões anteriores.
</p>
</>
)}
</>
)
)}
<p role="status">{decision.reason}</p>
<button type="button" onClick={() => onChange({ d: undefined })}>
Conservar dados e regressar ao vínculo individual deA (histórico
preservado)
</button>
</fieldset>
);
}