32 lines
6.1 KiB
TypeScript
32 lines
6.1 KiB
TypeScript
import {useState} from 'react';
|
|
import {goodsPresumptionBook,goodsPresumptionCurrent,goodsPresumptionReportRows,goodsPresumptionSource,goodsPresumptionTreatments,newGoodsPresumption,presumptionConditions,recordGoodsPresumptions,saveGoodsPresumptionBook,switchPresumptionTreatment,type GoodsPresumptionBook,type GoodsPresumptionRow} from '@/lib/iva-goods-presumptions';
|
|
export function SimulationGoodsPresumptions({draft,onChange}:{draft:Record<string,unknown>;onChange:(field:string,value:string)=>void}){
|
|
const[error,setError]=useState('');let book:GoodsPresumptionBook;
|
|
try{book=goodsPresumptionBook(draft);}catch(cause){return<p role="alert">{String(cause)}</p>;}
|
|
const save=(next:GoodsPresumptionBook)=>{try{onChange('modelo_a_snapshot',saveGoodsPresumptionBook(draft,next));setError('');}catch(cause){setError(String(cause));}};
|
|
const change=(id:string,patch:Partial<GoodsPresumptionRow>)=>save({...book,rows:book.rows.map(r=>r.id===id?{...r,...patch}:r)});
|
|
return <details className="rounded border p-3"><summary>Consignação e presunções de bens</summary>
|
|
<p>Uma linha por conjunto identificado. Na consignação,180dias contam da entrega ao destinatário. As presunções admitem prova em contrário. Classificação não concede isenção,dedução ou elegibilidade para margem.</p>
|
|
<p>Oportunidade: {String(draft.context_opportunity??'projecto')}. A data de conferência situa o cenário; este percurso não determina a exigibilidade,base ou IVA.</p>
|
|
<p className="text-sm">{goodsPresumptionSource}</p>{error&&<p role="alert">{error}</p>}
|
|
<button type="button" onClick={()=>save({...book,rows:[...book.rows,newGoodsPresumption(crypto.randomUUID())]})}>Acrescentar conjunto de bens</button>
|
|
{book.rows.map(row=><details key={row.id} className="rounded border p-3"><summary>{row.description||'Conjunto por identificar'} — {row.period||'mês por indicar'}</summary>
|
|
<div className="grid gap-3 md:grid-cols-2">
|
|
<label>Percurso de consignação/presunção<select value={row.treatment} onChange={e=>change(row.id,switchPresumptionTreatment(row,e.target.value))}><option value="">Por indicar</option>{goodsPresumptionTreatments.map(t=><option key={t.id} value={t.id}>{t.label}</option>)}</select></label>
|
|
<label>Natureza dos dados<select value={row.origin} onChange={e=>change(row.id,{origin:e.target.value as GoodsPresumptionRow['origin']})}><option value="projected">Projectados / pressupostos</option><option value="effective">Efectivos declarados</option></select></label>
|
|
{([['description','Conjunto/operação identificados'],['operationRef','Referência da operação / pressuposto'],['operationDate','Data de conferência / prevista'],['period','Mês da conferência'],['documentRef','Documento / referência da previsão'],['documentDate','Data do documento / prevista'],['goodsRef','Bens e elementos identificados'],['scope','Âmbito:conjunto,estabelecimentos,operação e período'],['evidence','Fundamento factual / pressupostos']] as const).map(([field,label])=><label key={field}>{label}<input className="block rounded border p-2" type={['operationDate','documentDate'].includes(field)?'date':field==='period'?'month':'text'} value={row[field]} onChange={e=>change(row.id,{[field]:e.target.value})}/></label>)}
|
|
{row.treatment==='consignment_180'?<><label>Data da entrega ao destinatário<input type="date" value={row.deliveryDate} onChange={e=>change(row.id,{deliveryDate:e.target.value})}/></label><label>Destinatário e referência da entrega<input value={row.recipientRef} onChange={e=>change(row.id,{recipientRef:e.target.value})}/></label><p>Identifique apenas o conjunto não devolvido. Separe devoluções parciais por conjunto; uma devolução posterior não apaga o cenário anteriormente guardado.</p></>:row.treatment&&<>
|
|
<label>Levantamento/inventário e estabelecimentos abrangidos<input value={row.inventoryRef} onChange={e=>change(row.id,{inventoryRef:e.target.value})}/></label>
|
|
{row.treatment==='excess_consumption'&&<>{([['quantity','Quantidade consumida'],['quantityUnit','Unidade da quantidade'],['productionRef','Volume de produção e comparação que fundamenta o excesso']] as const).map(([field,label])=><label key={field}>{label}<input value={row[field]} onChange={e=>change(row.id,{[field]:e.target.value})}/></label>)}<p>Sem percentagem ou limiar de consumo por defeito.</p></>}
|
|
<label>Existe prova em contrário para o âmbito declarado?<select value={row.contraryProof} onChange={e=>change(row.id,{contraryProof:e.target.value as GoodsPresumptionRow['contraryProof']})}><option value="">Por esclarecer</option><option value="yes">Sim</option><option value="no">Não</option></select></label>
|
|
{row.contraryProof==='yes'&&<label>Referência e âmbito da prova em contrário<input value={row.contraryProofRef} onChange={e=>change(row.id,{contraryProofRef:e.target.value})}/></label>}
|
|
</>}
|
|
</div>
|
|
<fieldset><legend>Factos próprios do percurso</legend>{presumptionConditions(row.treatment).map(([key,label])=><label className="block" key={key}>{label}<select value={row.conditions[key]??''} onChange={e=>change(row.id,{conditions:{...row.conditions,[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>)}</fieldset>
|
|
<p>Trocar percurso conserva dados/referências ocultos; reveja as confirmações aplicáveis. Prova em contrário afasta a presunção no seu âmbito,sem transformar o resultado em isenção.</p>
|
|
</details>)}
|
|
{!!book.rows.length&&<button type="button" onClick={()=>{try{save(recordGoodsPresumptions(draft,book));}catch(cause){setError(String(cause));}}}>Conferir consignação/presunções e guardar versão</button>}
|
|
{book.result&&<><p role="status">{goodsPresumptionCurrent(draft,book)?'Classificações correspondentes às entradas guardadas.':'Entradas alteradas;resultado histórico conservado.Reveja e confira novamente.'} {book.history?.length??0} versões anteriores.Sem IVA,base,dedução ou margem calculados.</p><dl>{goodsPresumptionReportRows(draft).map(([,label,value,origin],i)=><div key={i}><dt className="font-semibold">{label}</dt><dd>{value}<small className="block">{origin}</small></dd></div>)}</dl></>}
|
|
</details>;
|
|
}
|