342 lines
16 KiB
TypeScript
342 lines
16 KiB
TypeScript
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>
|
||
);
|
||
}
|