Files
Investidor-V2/resources/js/components/simulation-import-exemptions.tsx
T

34 lines
5.3 KiB
TypeScript

import { useState } from 'react';
import { importExemptionBook,importExemptionCurrent,importExemptionReportRows,importExemptionRules,importExemptionSource,newImportExemption,recordImportExemptions,saveImportExemptionBook,type ImportExemptionBook,type ImportExemptionRow } from '@/lib/iva-import-exemptions';
export function SimulationImportExemptions({draft,onChange}:{draft:Record<string,unknown>;onChange:(field:string,value:string)=>void}) {
const [error,setError]=useState('');
let book:ImportExemptionBook;
try {book=importExemptionBook(draft);}catch(cause){return <p role="alert">{String(cause)}</p>;}
const save=(next:ImportExemptionBook)=>{try {onChange('modelo_a_snapshot',saveImportExemptionBook(draft,next));setError('');}catch(cause){setError(String(cause));}};
const change=(id:string,patch:Partial<ImportExemptionRow>)=>save({...book,rows:book.rows.map(row=>row.id===id?{...row,...patch}:row)});
return <details className="space-y-3 rounded border p-3">
<summary>IVA na importação — reimportação no mesmo estado / ouro pelo Banco de Moçambique</summary>
<p>Oportunidade: {String(draft.context_opportunity||'entrada geral')}. Indique apenas importações relevantes. Estes dois ramos classificam a isenção em2026/MZN; as compras internas e os seus resultados conservam-se.</p>
<p>{importExemptionSource}</p>
<p>O valor declarado/previsional é conservado, sem o fixar como base aduaneira. A classificação não preenche o campo11 de dedução nem os totais do ModeloA. Uma condição não cumprida afasta só esta isenção; o imposto normal fica por enquadrar. Nas projecções, as respostas são pressupostos, sem certificação aduaneira.</p>
{error&&<p role="alert">{error}</p>}
<button type="button" className="underline" onClick={()=>save({...book,rows:[...book.rows,newImportExemption(crypto.randomUUID(),String(draft.currency??''))]})}>Acrescentar importação relevante</button>
{book.rows.map(row=>{
const rule=importExemptionRules.find(item=>item.id===row.treatment);
return <details key={row.id} className="rounded border p-3"><summary>{row.description||'Importação por identificar'} — {row.period||'mês por indicar'}</summary>
<div className="grid gap-3 md:grid-cols-2">
<label>Ramo da importação<select className="block rounded border p-2" value={row.treatment} onChange={e=>change(row.id,{treatment:e.target.value})}><option value="">Por indicar</option>{importExemptionRules.map(item=><option key={item.id} value={item.id}>{item.label}</option>)}</select></label>
<label>Natureza dos dados<select className="block rounded border p-2" value={row.origin} onChange={e=>change(row.id,{origin:e.target.value as ImportExemptionRow['origin']})}><option value="projected">Projectados / pressupostos</option><option value="effective">Efectivos declarados</option></select></label>
{(['description','importer','declaredValue','goodsCode','originCountry','documentRef','documentDate','period','evidence'] as const).map((field,index)=><label key={field}>{['Bens importados','Importador','Valor declarado / previsão (moeda indicada)','Código aduaneiro, se disponível','País de origem, se disponível','Documento aduaneiro / referência da previsão','Data do documento / prevista','Mês da importação','Fundamento factual das condições / pressupostos'][index]}<input className="block rounded border p-2" type={field==='documentDate'?'date':field==='period'?'month':'text'} value={row[field]} onChange={e=>change(row.id,{[field]:e.target.value})}/></label>)}
<label>Moeda de origem<input className="block rounded border p-2" value={row.currency} onChange={e=>change(row.id,{currency:e.target.value})}/></label>
</div>
{rule?<fieldset><legend>Condições de{rule.article}; respostas conservadas ao mudar de ramo</legend>{rule.conditions.map(([key,label])=><label className="block" key={key}>{label}<select className="block rounded border p-2" value={row.conditions[key]??''} onChange={e=>change(row.id,{conditions:{...row.conditions,[key]:e.target.value}})}><option value="">Por indicar</option><option value="yes">Sim</option><option value="no">Não</option></select></label>)}</fieldset>:<p>Escolha o ramo para apresentar apenas as condições aplicáveis; as respostas anteriores mantêm-se.</p>}
<p>Editar não substitui o resultado anterior. Ao classificar novamente, a versão anterior passa ao histórico.</p>
</details>;
})}
{!!book.rows.length&&<button type="button" className="rounded bg-emerald-800 p-2 text-white" onClick={()=>{try {save(recordImportExemptions(draft,book));}catch(cause){setError(String(cause));}}}>Classificar importações e guardar versão</button>}
{book.result&&<><p role="status">{importExemptionCurrent(draft,book)?'Classificação correspondente às entradas guardadas.':'Entradas alteradas; classificação histórica preservada. Reveja e classifique novamente.'} {book.history?.length??0} versões anteriores.</p><dl>{importExemptionReportRows(draft).map(([,label,value,origin],index)=><div key={index}><dt className="font-semibold">{label}</dt><dd>{value}<small className="block">{origin}</small></dd></div>)}</dl></>}
</details>;
}