Files
Investidor-V2/resources/js/components/simulation-objective-imports.tsx
T

416 lines
20 KiB
TypeScript

import { inputText } from '../lib/input-text.ts';
import { useState } from 'react';
import {
objectiveImportBook,
objectiveImportCurrent,
objectiveImportReportRows,
objectiveImportSource,
objectiveImportSources,
objectiveImportTreatments,
newObjectiveImport,
reuseObjectiveImport,
recordObjectiveImports,
saveObjectiveImportBook,
type ObjectiveImportBook,
type ObjectiveImportRow,
} from '@/lib/iva-objective-imports';
import { annexIEntries } from '@/lib/iva-annex-i';
import { pharmaAnnexEntries } from '@/lib/iva-pharma-annex';
export function SimulationObjectiveImports({
draft,
onChange,
}: {
draft: Record<string, unknown>;
onChange: (field: string, value: string) => void;
}) {
const [error, setError] = useState('');
let book: ObjectiveImportBook;
try {
book = objectiveImportBook(draft);
} catch (e) {
return <p role="alert">{String(e)}</p>;
}
const save = (next: ObjectiveImportBook) => {
try {
onChange('modelo_a_snapshot', saveObjectiveImportBook(draft, next));
setError('');
} catch (e) {
setError(String(e));
}
};
const change = (id: string, patch: Partial<ObjectiveImportRow>) =>
save({
...book,
rows: book.rows.map((r) => (r.id === id ? { ...r, ...patch } : r)),
});
let sources: ReturnType<typeof objectiveImportSources> = [];
try {
sources = objectiveImportSources(draft);
} catch {
/* Preserve unrecoverable source; direct entry remains independent. */
}
return (
<details className="rounded border p-3">
<summary>
Importações definitivas — isenção objectiva interna (P046)
</summary>
<p>
Analise a transmissão interna hipotética dos mesmos bens. Não é
necessário criar uma venda interna. A enumeração legal é
exemplificativa; este percurso cobre as correspondências
expressas implementadas. Outros fundamentos permanecem por
enquadrar.
</p>
<p>{objectiveImportSource}</p>
{error && <p role="alert">{error}</p>}
<button
type="button"
onClick={() =>
save({
...book,
rows: [
...book.rows,
newObjectiveImport(
crypto.randomUUID(),
inputText(draft.currency ?? ''),
),
],
})
}
>
Acrescentar importação objectiva
</button>
{book.rows.map((row) => {
const rule = objectiveImportTreatments.find(
(t) => t.id === row.reference.treatment,
);
return (
<details key={row.id}>
<summary>
{row.description || 'Importação por preparar'} —{' '}
{row.period || 'período por indicar'}
</summary>
{!!sources.length && (
<label>
Preencher campos em falta a partir de bens já
preparados
<select
value=""
onChange={(e) => {
const source = sources.find(
(s) => s.id === e.target.value,
);
if (source)
change(
row.id,
reuseObjectiveImport(
row,
source,
),
);
}}
>
<option value="">
Escolher origem sem sobrescrever edições
</option>
{sources.map((s) => (
<option key={s.id} value={s.id}>
{s.description} — {s.period}
</option>
))}
</select>
</label>
)}
{(
[
'description',
'period',
'importer',
'documentRef',
'documentDate',
'scope',
'evidence',
] as const
).map((field, i) => (
<label key={field} className="block">
{
[
'Bens desta importação',
'Período da importação',
'Importador',
'Documento aduaneiro ou previsão',
'Data do documento ou previsão',
'Âmbito: bens,operação,período e condições',
'Factos ou pressupostos expressos',
][i]
}
<input
type={
field === 'period'
? 'month'
: field === 'documentDate'
? 'date'
: 'text'
}
value={row[field]}
onChange={(e) =>
change(row.id, {
[field]: e.target.value,
})
}
/>
</label>
))}
<label>
Natureza dos dados
<select
value={row.origin}
onChange={(e) =>
change(row.id, {
origin: e.target
.value as ObjectiveImportRow['origin'],
})
}
>
<option value="projected">
Pressupostos de projecção
</option>
<option value="effective">
Factos efectivos declarados
</option>
</select>
</label>
{(
[
'definitive',
'goods',
'sameGoods',
'internalApplicable',
] as const
).map((field, i) => (
<label key={field} className="block">
{
[
'Importação definitiva',
'A operação importa bens,não um serviço',
'Correspondência refere-se aos mesmos bens e âmbito desta importação',
'Isenção objectiva interna aplicável na hipótese destes bens',
][i]
}
<select
value={row[field]}
onChange={(e) =>
change(row.id, {
[field]: e.target.value,
})
}
>
<option value="">Por esclarecer</option>
<option value="yes">Sim</option>
<option value="no">Não</option>
</select>
</label>
))}
<label>
Correspondência da isenção interna
<select
value={row.reference.treatment}
onChange={(e) =>
change(row.id, {
reference: {
...row.reference,
treatment: e.target.value,
confirmed: [],
},
internalApplicable: '',
})
}
>
<option value="other">
Escolher correspondência
</option>
{objectiveImportTreatments.map((t) => (
<option key={t.id} value={t.id}>
{t.label}
</option>
))}
</select>
</label>
{rule && (
<>
<p>
{rule.article}. As condições seguintes
referem-se à hipótese de transmissão no
território nacional dos bens identificados;
não ao fornecedor estrangeiro. Trocar
correspondência conserva anexos em rascunho
e limpa confirmações.
</p>
{rule.conditions.map((condition, i) => (
<label className="block" key={i}>
<input
type="checkbox"
checked={row.reference.confirmed.includes(
i,
)}
onChange={(e) =>
change(row.id, {
reference: {
...row.reference,
confirmed: e.target
.checked
? [
...row
.reference
.confirmed,
i,
]
: row.reference.confirmed.filter(
(n) =>
n !== i,
),
},
})
}
/>
{i === 0
? 'A transmissão interna hipotética estaria localizada em Moçambique; a operação real analisada continua a ser a importação'
: condition}
</label>
))}
</>
)}
{row.reference.treatment === 'annexI_goods' && (
<>
<label>
Posição do Anexo I
<select
value={row.reference.annexIItem ?? ''}
onChange={(e) =>
change(row.id, {
reference: {
...row.reference,
annexIItem: e.target.value,
confirmed: [],
},
})
}
>
<option value="">Por indicar</option>
{annexIEntries.map((a) => (
<option key={a.id} value={a.id}>
{a.code} — {a.label}
</option>
))}
</select>
</label>
<label>
Após conferir os outros
tratamentos,corresponde apenas a9(12)h?
<select
value={
row.reference.annexIOnly ===
undefined
? ''
: row.reference.annexIOnly
? 'yes'
: 'no'
}
onChange={(e) =>
change(row.id, {
reference: {
...row.reference,
annexIOnly:
e.target.value === ''
? undefined
: e.target.value ===
'yes',
},
})
}
>
<option value="">Por esclarecer</option>
<option value="yes">
Sim,com fundamento nos factos
indicados
</option>
<option value="no">
Não;escolher correspondência
específica
</option>
</select>
</label>
</>
)}
{row.reference.treatment ===
'pharma_manufacturing_inputs' && (
<label>
Posição do Anexo III
<select
value={row.reference.pharmaAnnexItem ?? ''}
onChange={(e) =>
change(row.id, {
reference: {
...row.reference,
pharmaAnnexItem: e.target.value,
confirmed: [],
},
})
}
>
<option value="">Por indicar</option>
{pharmaAnnexEntries.map((a) => (
<option key={a.id} value={a.id}>
{a.code} — {a.label}
</option>
))}
</select>
</label>
)}
</details>
);
})}
{!!book.rows.length && (
<button
type="button"
onClick={() => {
try {
save(recordObjectiveImports(draft, book));
} catch (e) {
setError(String(e));
}
}}
>
Conferir importações objectivas e guardar versão
</button>
)}
{book.result && (
<>
<p role="status">
{objectiveImportCurrent(draft, book)
? 'Resultado corresponde às entradas guardadas.'
: 'Entradas alteradas;resultado histórico conservado.'}{' '}
{book.history?.length ?? 0} versões anteriores. Sem
dedução ou soma aos livros internos.
</p>
<dl>
{objectiveImportReportRows(draft).map(
([, label, value, origin], i) => (
<div key={i}>
<dt>{label}</dt>
<dd>
{value}
<small className="block">
{origin}
</small>
</dd>
</div>
),
)}
</dl>
</>
)}
</details>
);
}