30 lines
6.0 KiB
TypeScript
30 lines
6.0 KiB
TypeScript
import {useState} from 'react';
|
|
import {newActSaleBase,switchActValuation,switchActKind,actSaleBook,actSaleConditions,actSaleCurrent,actSaleReportRows,actSaleBaseSource,actSaleKinds,actSaleTreatments,recordActSaleBases,saveActSaleBook,type ActSaleBook,type ActSaleRow} from '@/lib/iva-act-sale-base';
|
|
|
|
export function SimulationActSaleBase({draft,onChange}:{draft:Record<string,unknown>;onChange:(field:string,value:string)=>void}){
|
|
const[error,setError]=useState('');let book:ActSaleBook;
|
|
try{book=actSaleBook(draft);}catch(cause){return<p role="alert">{String(cause)}</p>;}
|
|
const save=(next:ActSaleBook)=>{try{onChange('modelo_a_snapshot',saveActSaleBook(draft,next));setError('');}catch(cause){setError(String(cause));}};
|
|
const change=(id:string,patch:Partial<ActSaleRow>)=>save({...book,rows:book.rows.map(row=>row.id===id?{...row,...patch}:row)});
|
|
return<details className="space-y-3 rounded border p-3">
|
|
<summary>Base tributável — arrematação e outros actos de transmissão</summary>
|
|
<p>Oportunidade: {String(draft.context_opportunity||'entrada geral')}. Prepare apenas transmissões de bens resultantes dos actos abrangidos pelo artigo15(2)(h). Indique o valor por que a arrematação/venda foi efectuada ou,se for caso,o valor normal dos bens. O portal não escolhe o menor valor nem transforma um pagamento ou acordo genérico numa transmissão sujeita a IVA.</p>
|
|
<p>Na conciliação ou transacção,identifique a transmissão dos bens e o fundamento do valor aplicável; não basta o montante genérico do acordo. O valor normal exige fundamento e âmbito identificados,não um certificado ou avaliador criado pelo portal. Base e IVA são resultados distintos.</p>
|
|
<p>{actSaleBaseSource}</p>{error&&<p role="alert">{error}</p>}
|
|
<button type="button" className="underline" onClick={()=>save({...book,rows:[...book.rows,newActSaleBase(crypto.randomUUID(),String(draft.currency??''))]})}>Acrescentar transmissão por acto</button>
|
|
{book.rows.map(row=>{const rule=actSaleTreatments.find(item=>item.id===row.treatment);return<details key={row.id} className="rounded border p-3"><summary>{row.description||'Transmissão por identificar'} — {row.period||'mês por indicar'}</summary>
|
|
<div className="grid gap-3 md:grid-cols-2">
|
|
<label>Natureza do acto<select className="block rounded border p-2" value={row.actKind} onChange={e=>change(row.id,switchActKind(row,e.target.value))}><option value="">Por indicar</option>{actSaleKinds.map(item=><option key={item.id} value={item.id}>{item.label}</option>)}</select></label>
|
|
<label>Fundamento do valor aplicável<select className="block rounded border p-2" value={row.treatment} onChange={e=>change(row.id,switchActValuation(row,e.target.value))}><option value="">Por indicar</option>{actSaleTreatments.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 ActSaleRow['origin']})}><option value="projected">Projectados / pressupostos</option><option value="effective">Efectivos declarados</option></select></label>
|
|
{([['description','Bens e transmissão identificados'],['actRef','Acto ou contrato / referência da previsão'],['documentRef','Documento da transmissão / referência da previsão'],['documentDate','Data do documento / prevista'],['period','Mês da transmissão'],['currency','Moeda de origem'],['valuationRef','Referência documental / pressuposto da valorização'],['valuationScope','Âmbito da valorização: bens, operação, período e condições'],['compositionRef','Referência da composição sem IVA — inclusões e exclusões aplicáveis'],['evidence','Fundamento factual / pressupostos']] as const).map(([field,label])=><label key={field}>{label}<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>)}
|
|
{rule&&<label>{row.treatment==='act_sale_amount'?'Valor da arrematação ou venda efectuada,sem IVA (moeda indicada)':'Valor normal dos bens,sem IVA (moeda indicada)'}<input className="block rounded border p-2" value={row.treatment==='act_sale_amount'?row.actValue:row.normalValue} onChange={e=>change(row.id,{[row.treatment==='act_sale_amount'?'actValue':'normalValue']:e.target.value})}/></label>}
|
|
</div>
|
|
<p>Mudar de acto ou fundamento conserva os montantes e documentos,mas exige rever a correspondência dos bens e da valorização antes de determinar a base. As versões anteriores mantêm-se.</p>
|
|
{rule?<fieldset><legend>Condições próprias desta transmissão</legend>{actSaleConditions.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 fundamento para apresentar o montante aplicável;os valores anteriores conservam-se.</p>}
|
|
</details>;})}
|
|
{!!book.rows.length&&<button type="button" className="rounded bg-emerald-800 p-2 text-white" onClick={()=>{try{save(recordActSaleBases(draft,book));}catch(cause){setError(String(cause));}}}>Determinar bases de transmissão e guardar versão</button>}
|
|
{book.result&&<><p role="status">{actSaleCurrent(draft,book)?'Bases de transmissão correspondentes às entradas guardadas.':'Entradas alteradas;bases de transmissão históricas conservadas. Reveja e determine novamente.'} {book.history?.length??0} versões anteriores. IVA e campo11 não são preenchidos por estas bases.</p><dl>{actSaleReportRows(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>;
|
|
}
|