33 lines
6.6 KiB
TypeScript
33 lines
6.6 KiB
TypeScript
import {useState} from 'react';
|
|
import {newValueReview,switchValueReview,switchPriceContext,switchValueOrigin,valueReviewBook,valueReviewConditions,valueReviewCurrent,valueReviewReportRows,valueReviewSource,valueReviewTreatments,priceContexts,recordValueReviews,saveValueReviewBook,type ValueReviewBook,type ValueReviewRow} from '@/lib/iva-value-review';
|
|
|
|
export function SimulationValueReview({draft,onChange}:{draft:Record<string,unknown>;onChange:(field:string,value:string)=>void}){
|
|
const[error,setError]=useState('');let book:ValueReviewBook;
|
|
try{book=valueReviewBook(draft);}catch(cause){return<p role="alert">{String(cause)}</p>;}
|
|
const save=(next:ValueReviewBook)=>{try{onChange('modelo_a_snapshot',saveValueReviewBook(draft,next));setError('');}catch(cause){setError(String(cause));}};
|
|
const change=(id:string,patch:Partial<ValueReviewRow>)=>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 — comparação de preços e correcção referenciada</summary>
|
|
<p>Oportunidade: {String(draft.context_opportunity||'entrada geral')}. Compare a contraprestação com o preço corrente ou normal correspondente à natureza da operação. Um preço inferior permite à AT proceder à correcção;esta comparação não exerce esse poder nem substitui automaticamente a contraprestação.</p>
|
|
<p>Para registar uma correcção,identifique o montante,referência,data e âmbito aplicáveis à operação e período. Na projecção,um cenário condicionado permanece identificado como pressuposto,não decisão AT concedida. Base e IVA são resultados distintos.</p>
|
|
<p>{valueReviewSource}</p>{error&&<p role="alert">{error}</p>}
|
|
<button type="button" className="underline" onClick={()=>save({...book,rows:[...book.rows,newValueReview(crypto.randomUUID(),String(draft.currency??''))]})}>Acrescentar comparação de contraprestação</button>
|
|
{book.rows.map(row=><details key={row.id} className="rounded border p-3"><summary>{row.description||'Operação por identificar'} — {row.period||'mês por indicar'}</summary>
|
|
<div className="grid gap-3 md:grid-cols-2">
|
|
<label>Percurso da comparação<select className="block rounded border p-2" value={row.treatment} onChange={e=>change(row.id,switchValueReview(row,e.target.value))}><option value="">Por indicar</option>{valueReviewTreatments.map(t=><option key={t.id} value={t.id}>{t.label}</option>)}</select></label>
|
|
<label>Contexto do preço de referência<select className="block rounded border p-2" value={row.priceContext} onChange={e=>change(row.id,switchPriceContext(row,e.target.value))}><option value="">Por indicar</option>{priceContexts.map(t=><option key={t.id} value={t.id}>{t.label}</option>)}</select></label>
|
|
<label>Natureza dos dados<select className="block rounded border p-2" value={row.origin} onChange={e=>change(row.id,switchValueOrigin(row,e.target.value as ValueReviewRow['origin']))}><option value="projected">Projectados / pressupostos</option><option value="effective">Efectivos declarados</option></select></label>
|
|
{([['description','Operação identificada'],['operationRef','Referência da operação / pressuposto'],['documentRef','Documento da operação / referência da previsão'],['documentDate','Data do documento / prevista'],['period','Mês da operação'],['currency','Moeda de origem'],['declaredAmount','Contraprestação declarada sem IVA (moeda indicada)'],['referenceAmount','Preço corrente ou normal comparável sem IVA (moeda indicada)'],['referenceRef','Referência do preço corrente ou normal / pressuposto'],['referenceScope','Âmbito do preço: bens/serviços, estádio, período, local e condições'],['compositionRef','Referência da composição equivalente sem próprio IVA'],['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>)}
|
|
{row.treatment==='referenced_correction'&&<>
|
|
{([['correctedAmount','Montante da base corrigida / pressuposto condicionado'],['correctionRef','Referência da correcção AT / pressuposto condicionado'],['correctionScope','Âmbito da correcção: bens/serviços, operação, período e condições'],['correctionDate','Data da correcção / prevista']] as const).map(([field,label])=><label key={field}>{label}<input className="block rounded border p-2" type={field==='correctionDate'?'date':'text'} value={row[field]} onChange={e=>change(row.id,{[field]:e.target.value})}/></label>)}
|
|
<label>{row.origin==='projected'?'O cenário condicionado assume expressamente esta correcção e âmbito,sem afirmar decisão AT concedida?':'A correcção AT referenciada aplica-se a estes bens/serviços,operação,período e condições?'}<select className="block rounded border p-2" value={row.correctionApplies} onChange={e=>change(row.id,{correctionApplies:e.target.value as ValueReviewRow['correctionApplies']})}><option value="">Por indicar</option><option value="yes">Sim</option><option value="no">Não</option></select></label>
|
|
</>}
|
|
</div>
|
|
<p>Mudar percurso/contexto conserva montantes e documentos,mas exige rever as correspondências afectadas. Campos sem aplicação ficam ocultos e conservados;uma comparação não concede nem determina uma correcção.</p>
|
|
<fieldset><legend>Condições próprias da comparação</legend>{valueReviewConditions.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>
|
|
</details>)}
|
|
{!!book.rows.length&&<button type="button" className="rounded bg-emerald-800 p-2 text-white" onClick={()=>{try{save(recordValueReviews(draft,book));}catch(cause){setError(String(cause));}}}>Comparar e guardar versão</button>}
|
|
{book.result&&<><p role="status">{valueReviewCurrent(draft,book)?'Comparações correspondentes às entradas guardadas.':'Entradas alteradas;comparações 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>{valueReviewReportRows(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>;
|
|
}
|