36 lines
6.1 KiB
TypeScript
36 lines
6.1 KiB
TypeScript
import {useState} from 'react';
|
|
import {newReducedBase,switchReducedTreatment,reducedBaseBook,reducedBaseConditions,ownReducedConditions,reducedBaseCurrent,reducedBaseReportRows,reducedBaseSource,reducedBaseTreatments,publicWorkCategories,recordReducedBases,saveReducedBaseBook,type ReducedBaseBook,type ReducedBaseRow} from '@/lib/iva-reduced-bases';
|
|
|
|
export function SimulationReducedBases({draft,onChange}:{draft:Record<string,unknown>;onChange:(field:string,value:string)=>void}){
|
|
const[error,setError]=useState('');let book:ReducedBaseBook;
|
|
try{book=reducedBaseBook(draft);}catch(cause){return<p role="alert">{String(cause)}</p>;}
|
|
const save=(next:ReducedBaseBook)=>{try{onChange('modelo_a_snapshot',saveReducedBaseBook(draft,next));setError('');}catch(cause){setError(String(cause));}};
|
|
const change=(id:string,patch:Partial<ReducedBaseRow>)=>save({...book,rows:book.rows.map(row=>row.id===id?{...row,...patch}:row)});
|
|
return<details className="space-y-3 rounded border p-3">
|
|
<summary>Bases reduzidas — energia,taxas aeronáuticas,obras públicas eágua</summary>
|
|
<p>Oportunidade: {String(draft.context_opportunity||'entrada geral')}. Indique a contraprestação total antes da redução,sem o próprioIVA ecom a composição conferida. Se o montante já está reduzido,reutilize o valor original antes de calcular;se só existe total comIVA,esclareça a composição antes de usar este campo.</p>
|
|
<p>Energia62%,taxas aeronáuticas85%,obras públicas40%(redução60%)eágua75%. Percentagem da base não é taxaIVA. A dedução relativa a estas operações fica sujeita à mesma proporção18(6),mas este percurso não calcula nem concede dedução ou preenche campo11.</p>
|
|
<p>{reducedBaseSource}</p>{error&&<p role="alert">{error}</p>}
|
|
<button type="button" className="underline" onClick={()=>save({...book,rows:[...book.rows,newReducedBase(crypto.randomUUID(),String(draft.currency??''))]})}>Acrescentar base reduzida</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>Tratamento da base reduzida<select className="block rounded border p-2" value={row.treatment} onChange={e=>change(row.id,switchReducedTreatment(row,e.target.value))}><option value="">Por indicar</option>{reducedBaseTreatments.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,{origin:e.target.value as ReducedBaseRow['origin']})}><option value="projected">Projectados / pressupostos</option><option value="effective">Efectivos declarados</option></select></label>
|
|
{([['description','Operação identificada'],['currency','Moeda do montante'],['operationDate','Data da operação / prevista'],['period','Mês da operação'],['documentRef','Documento / referência da previsão'],['documentDate','Data do documento / prevista'],['priceScope','Âmbito:objecto,operação,local eperíodo'],['consideration','Contraprestação total antes da redução,sem próprioIVA'],['compositionRef','Referência da composição15(1)/(5)/(6)'],['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==='public_works'?<>
|
|
<label>Projecto ou contrato de obra pública<input className="block rounded border p-2" value={row.projectRef} onChange={e=>change(row.id,{projectRef:e.target.value})}/></label>
|
|
<label>Categoria da obra<select className="block rounded border p-2" value={row.workCategory} onChange={e=>change(row.id,{workCategory:e.target.value})}><option value="">Por indicar</option>{publicWorkCategories.map(c=><option key={c.id} value={c.id}>{c.label}</option>)}</select></label>
|
|
</>:row.treatment&&<>
|
|
<label>Referência do preço fixado ou taxa aeronáutica<input className="block rounded border p-2" value={row.priceRef} onChange={e=>change(row.id,{priceRef:e.target.value})}/></label>
|
|
<label>Preço/taxa aplicável desde<input type="date" className="block rounded border p-2" value={row.priceFrom} onChange={e=>change(row.id,{priceFrom:e.target.value})}/></label>
|
|
<label>Preço/taxa aplicável até,se houver termo<input type="date" className="block rounded border p-2" value={row.priceTo} onChange={e=>change(row.id,{priceTo:e.target.value})}/></label>
|
|
</>}
|
|
</div>
|
|
<p>Mudar tratamento conserva dados e referências ocultos,mas exige rever os factos próprios. Não se exige referência de preço fixado para obras públicas;estas dependem do projecto/categoria/âmbito aplicáveis.</p>
|
|
<fieldset><legend>Condições deste tratamento</legend>{[...reducedBaseConditions,...ownReducedConditions(row.treatment)].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 as ''|'yes'|'no'}})}><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(recordReducedBases(draft,book));}catch(cause){setError(String(cause));}}}>Calcular bases reduzidas e guardar versão</button>}
|
|
{book.result&&<><p role="status">{reducedBaseCurrent(draft,book)?'Bases correspondentes às entradas guardadas.':'Entradas alteradas;bases históricas conservadas. Reveja e calcule novamente.'} {book.history?.length??0} versões anteriores. Base eproporção18(6)não são imposto ou dedução concedida.</p><dl>{reducedBaseReportRows(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>;
|
|
}
|