380 lines
17 KiB
TypeScript
380 lines
17 KiB
TypeScript
import type { Acquisition } from '@/lib/iva-acquisitions';
|
||
import {
|
||
acquisitionImportSources,
|
||
expenseOptions,
|
||
newAcquisitionBC,
|
||
reuseAcquisitionImport,
|
||
type AcquisitionBC,
|
||
} from '@/lib/iva-acquisition-bc';
|
||
export function AcquisitionImportsExclusions({
|
||
draft,
|
||
row,
|
||
onChange,
|
||
}: {
|
||
draft: Record<string, unknown>;
|
||
row: Acquisition;
|
||
onChange: (patch: Partial<Acquisition>) => void;
|
||
}) {
|
||
const b = row.bc;
|
||
const update = (patch: Partial<AcquisitionBC>) =>
|
||
onChange({ bc: { ...(b ?? newAcquisitionBC()), ...patch } });
|
||
const choice = (
|
||
key: 'reducedSupply' | 'belongs' | 'ownImportVat',
|
||
label: string,
|
||
) => (
|
||
<label className="block">
|
||
{label}
|
||
<select
|
||
value={b?.[key] ?? ''}
|
||
onChange={(e) => update({ [key]: e.target.value })}
|
||
>
|
||
<option value="">Por indicar</option>
|
||
<option value="yes">Sim</option>
|
||
<option value="no">Não</option>
|
||
</select>
|
||
</label>
|
||
);
|
||
const fact = (key: string, label: string) => (
|
||
<label className="block" key={key}>
|
||
{label}
|
||
<select
|
||
value={b?.facts[key] ?? ''}
|
||
onChange={(e) =>
|
||
update({
|
||
facts: {
|
||
...b?.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>
|
||
);
|
||
if (!b)
|
||
return (
|
||
<div>
|
||
<button
|
||
type="button"
|
||
onClick={() => onChange({ bc: newAcquisitionBC() })}
|
||
>
|
||
Analisar exclusões e excepções desta aquisição — C
|
||
</button>
|
||
<button
|
||
type="button"
|
||
onClick={() =>
|
||
onChange({
|
||
bc: newAcquisitionBC(),
|
||
field: '11',
|
||
domestic: 'no',
|
||
documentType: 'customs',
|
||
})
|
||
}
|
||
>
|
||
Preparar importação — B/campo11 (conserva valores e
|
||
documento)
|
||
</button>
|
||
</div>
|
||
);
|
||
const imported = row.domestic === 'no';
|
||
const sources = acquisitionImportSources(draft);
|
||
return (
|
||
<fieldset className="space-y-2 rounded border p-3">
|
||
<legend>Importações e exclusões — B/C</legend>
|
||
<p>
|
||
Dados existentes conservados;as respostas são factos declarados
|
||
ou pressupostos de projecção. Informação em falta fica
|
||
indeterminada. Alterar a natureza da despesa conserva respostas
|
||
anteriores sem as aplicar a outro tratamento.
|
||
</p>
|
||
{imported && (
|
||
<>
|
||
<p>
|
||
Campo11:IVA devido na importação de bens pelo documento
|
||
aduaneiro. Não calcula direitosL13,não copia o valor
|
||
aduaneiro como IVA e não exige fornecedor estrangeiro
|
||
inscrito no IVA interno.
|
||
</p>
|
||
<label className="block">
|
||
Reutilizar registo de importação existente
|
||
<select
|
||
value=""
|
||
onChange={(e) => {
|
||
const source = sources.find(
|
||
(s) =>
|
||
s.map + '/' + s.row.id ===
|
||
e.target.value,
|
||
);
|
||
if (source)
|
||
onChange(
|
||
reuseAcquisitionImport(
|
||
draft,
|
||
row,
|
||
source.map,
|
||
source.row.id,
|
||
),
|
||
);
|
||
}}
|
||
>
|
||
<option value="">
|
||
Escolher correspondência;apenas preenche dados
|
||
vazios
|
||
</option>
|
||
{sources.map((s) => (
|
||
<option
|
||
key={s.map + '/' + s.row.id}
|
||
value={s.map + '/' + s.row.id}
|
||
>
|
||
{s.label}
|
||
</option>
|
||
))}
|
||
</select>
|
||
</label>
|
||
{b.source && (
|
||
<p>
|
||
Origem conservada:{b.source.map}/{b.source.id}.
|
||
Reutilizar novamente adopta a origem actual,sem
|
||
substituir edições.
|
||
</p>
|
||
)}
|
||
{(['importer', 'goodsRef', 'vatRef'] as const).map(
|
||
(key, i) => (
|
||
<label className="block" key={key}>
|
||
{
|
||
[
|
||
'Importador identificado',
|
||
'Bens/operação/linha abrangidos',
|
||
'Fonte do montante de IVA devido — bilhete/pressuposto',
|
||
][i]
|
||
}
|
||
<input
|
||
value={b[key]}
|
||
onChange={(e) =>
|
||
update({ [key]: e.target.value })
|
||
}
|
||
/>
|
||
</label>
|
||
),
|
||
)}
|
||
{choice(
|
||
'belongs',
|
||
'Bilhete na titularidade do sujeito passivo/importador desta aquisição',
|
||
)}
|
||
{fact(
|
||
'exigibleInPeriod',
|
||
'IVA aduaneiro tornou-se exigível no período de dedução indicado,conforme a fonte/documento21(1);não basta a data de emissão do bilhete',
|
||
)}
|
||
{choice(
|
||
'ownImportVat',
|
||
'Montante é apenas IVA próprio devido nesta importação,sem somar novamente IVA de serviço incluído na base dos bens',
|
||
)}
|
||
<label className="block">
|
||
Situação do IVA da importação
|
||
<select
|
||
value={b.vatBasis}
|
||
onChange={(e) =>
|
||
update({
|
||
vatBasis: e.target
|
||
.value as AcquisitionBC['vatBasis'],
|
||
})
|
||
}
|
||
>
|
||
<option value="">Por identificar</option>
|
||
<option value="due">
|
||
IVA devido identificado no documento/pressuposto
|
||
</option>
|
||
<option value="exempt">
|
||
Importação isenta — IVAzero expressamente
|
||
indicado
|
||
</option>
|
||
<option value="zero">
|
||
Montantezero expresso,com fundamento
|
||
</option>
|
||
<option value="unknown">
|
||
Montante desconhecido
|
||
</option>
|
||
</select>
|
||
</label>
|
||
<p>
|
||
IVA isento/zero não é montante desconhecido. Para
|
||
ausência de imposto a deduzir,indique zero expressamente
|
||
no IVA;isençãoL1 não preenche esse montante.
|
||
</p>
|
||
</>
|
||
)}
|
||
{!imported &&
|
||
choice(
|
||
'reducedSupply',
|
||
'O IVA suportado respeita a fornecimento abrangido pelo artigo17-A (20(2))',
|
||
)}
|
||
<label className="block">
|
||
Natureza da despesa para dedução
|
||
<select
|
||
value={b.expense}
|
||
onChange={(e) => update({ expense: e.target.value })}
|
||
>
|
||
<option value="">Por identificar</option>
|
||
{expenseOptions.map(([v, l]) => (
|
||
<option key={v} value={v}>
|
||
{l}
|
||
</option>
|
||
))}
|
||
</select>
|
||
</label>
|
||
{b.expense === 'vehicle' && (
|
||
<>
|
||
{fact(
|
||
'tourism',
|
||
'Bem abrangido20(1)(a):viatura de turismo,barco de recreio,helicóptero,avião,moto/motociclo. Viatura:inclui reboque;não destinada unicamente a mercadorias/uso agrícola,comercial ou industrial,ou mista/passageiros até9lugares incluindo condutor',
|
||
)}
|
||
{b.facts.tourism === 'yes' &&
|
||
fact(
|
||
'saleOrExploit',
|
||
'Venda ou exploração deste bem constitui objecto da actividade20(3)(a)',
|
||
)}
|
||
</>
|
||
)}
|
||
{b.expense === 'fuel' && (
|
||
<>
|
||
{fact(
|
||
'resale',
|
||
'Combustível adquirido para revenda,com actividade e destino identificados20(3)(a)',
|
||
)}
|
||
{b.facts.resale === 'no' && (
|
||
<>
|
||
<label>
|
||
Combustível
|
||
<select
|
||
value={b.fuelKind}
|
||
onChange={(e) =>
|
||
update({
|
||
fuelKind: e.target
|
||
.value as AcquisitionBC['fuelKind'],
|
||
})
|
||
}
|
||
>
|
||
<option value="">Por identificar</option>
|
||
<option value="diesel">Gasóleo</option>
|
||
<option value="other">
|
||
Outro combustível normalmente utilizável
|
||
em viaturas
|
||
</option>
|
||
</select>
|
||
</label>
|
||
{b.fuelKind === 'diesel' && (
|
||
<>
|
||
<label>
|
||
Utilização do gasóleo
|
||
<select
|
||
value={b.dieselUse}
|
||
onChange={(e) =>
|
||
update({
|
||
dieselUse: e.target
|
||
.value as AcquisitionBC['dieselUse'],
|
||
})
|
||
}
|
||
>
|
||
<option value="">
|
||
Por identificar
|
||
</option>
|
||
<option value="heavy_passengers">
|
||
Veículo pesado de passageiros
|
||
</option>
|
||
<option value="public_passengers">
|
||
Veículo licenciado para
|
||
transporte público de
|
||
passageiros,excepto rent a car
|
||
</option>
|
||
<option value="machine">
|
||
Máquina consumidora de gasóleo
|
||
que não é veículo matriculado
|
||
</option>
|
||
<option value="agriculture">
|
||
Tractor com emprego
|
||
exclusivo/predominante em
|
||
operações inerentes à actividade
|
||
agrícola
|
||
</option>
|
||
<option value="other">
|
||
Outro uso — dedução50%
|
||
</option>
|
||
</select>
|
||
</label>
|
||
{b.dieselUse &&
|
||
b.dieselUse !== 'other' &&
|
||
fact(
|
||
'dieselScope',
|
||
'O uso e as características correspondem integralmente à categoria20(1)(b)(i–iv) seleccionada',
|
||
)}
|
||
</>
|
||
)}
|
||
</>
|
||
)}
|
||
</>
|
||
)}
|
||
{b.expense === 'lodging_food' &&
|
||
fact(
|
||
'commercialTraveller',
|
||
'Alojamento/alimentação de viajante comercial,agindo por conta própria,no quadro da actividade profissional20(3)(b)',
|
||
)}
|
||
{b.expense === 'telephone' &&
|
||
fact(
|
||
'ownLandline',
|
||
'Serviço de telefone fixo em nome do sujeito passivo20(1)(e)',
|
||
)}
|
||
{b.expense === 'beverages' && (
|
||
<>
|
||
{fact(
|
||
'beverageSpecial',
|
||
'Bebidas de abastecimento de bordo nas alíneas13(1)(c/d/h),com origemL1 identificada;tabaco e recepção não estão abrangidos por esta excepção',
|
||
)}
|
||
{b.facts.beverageSpecial === 'yes' && (
|
||
<>
|
||
<label>
|
||
Via13(2) para esta parcela
|
||
<select
|
||
value={b.beveragePath}
|
||
onChange={(e) =>
|
||
update({
|
||
beveragePath: e.target
|
||
.value as AcquisitionBC['beveragePath'],
|
||
})
|
||
}
|
||
>
|
||
<option value="">Por escolher</option>
|
||
<option value="deduction">
|
||
Dedução nesta aquisição — L2
|
||
</option>
|
||
<option value="refund">
|
||
RestituiçãoL3-E — sem dedução desta
|
||
parcela
|
||
</option>
|
||
</select>
|
||
</label>
|
||
{b.beveragePath === 'deduction' &&
|
||
fact(
|
||
'onlyDeduction',
|
||
'Parcela identificada exclusivamente para dedução;sem pedido/restituição da mesma parcela',
|
||
)}
|
||
{fact(
|
||
'notCoastalFishing',
|
||
'Se origem13(1)(d):embarcação de salvamento/assistência marítima,sem ser pesca costeira cujas provisões ficam excluídas',
|
||
)}
|
||
</>
|
||
)}
|
||
</>
|
||
)}
|
||
<label className="block">
|
||
Factos e referência documental da classificação/excepção
|
||
<input
|
||
value={b.evidence}
|
||
onChange={(e) => update({ evidence: e.target.value })}
|
||
/>
|
||
</label>
|
||
</fieldset>
|
||
);
|
||
}
|