Files
Investidor-V2/resources/js/components/simulation-fuel-base.tsx
T

30 lines
5.9 KiB
TypeScript

import {useState} from 'react';
import {newFuelBase,switchFuelTaxTreatment,fuelBaseBook,fuelBaseConditions,fuelBaseCurrent,fuelBaseReportRows,fuelBaseSource,fuelBaseTreatments,recordFuelBases,saveFuelBaseBook,type FuelBaseBook,type FuelBaseRow} from '@/lib/iva-fuel-base';
export function SimulationFuelBase({draft,onChange}:{draft:Record<string,unknown>;onChange:(field:string,value:string)=>void}){
const[error,setError]=useState('');let book:FuelBaseBook;
try{book=fuelBaseBook(draft);}catch(cause){return<p role="alert">{String(cause)}</p>;}
const save=(next:FuelBaseBook)=>{try{onChange('modelo_a_snapshot',saveFuelBaseBook(draft,next));setError('');}catch(cause){setError(String(cause));}};
const change=(id:string,patch:Partial<FuelBaseRow>)=>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 — combustíveis com preço fixado</summary>
<p>Oportunidade: {String(draft.context_opportunity||'entrada geral')}. Prepare transmissões por revendedores de combustíveis cujo preço é fixado pela Autoridade Pública. Identifique a referência e o âmbito temporal do preço aplicável;na projecção,pode declarar pressupostos expressos. Não se presume um preço actual para outro período.</p>
<p>A base exclui a Taxa sobre Combustíveis (TC). Se o montante já a exclui,não se subtrai novamente. Indique valores sem o próprio IVA e com a composição aplicável identificada. Base e IVA são resultados distintos.</p>
<p>{fuelBaseSource}</p>{error&&<p role="alert">{error}</p>}
<button type="button" className="underline" onClick={()=>save({...book,rows:[...book.rows,newFuelBase(crypto.randomUUID(),String(draft.currency??''))]})}>Acrescentar transmissão de combustível</button>
{book.rows.map(row=>{const rule=fuelBaseTreatments.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>Composição quanto à TC<select className="block rounded border p-2" value={row.treatment} onChange={e=>change(row.id,switchFuelTaxTreatment(row,e.target.value))}><option value="">Por indicar</option>{fuelBaseTreatments.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 FuelBaseRow['origin']})}><option value="projected">Projectados / pressupostos</option><option value="effective">Efectivos declarados</option></select></label>
{([['description','Combustível e transmissão identificados'],['operationDate','Data da transmissão / prevista'],['period','Mês da transmissão'],['currency','Moeda de origem'],['priceRef','Referência do preço fixado / pressuposto'],['priceScope','Âmbito do preço: combustível, operação, local e condições'],['priceFrom','Preço aplicável desde / pressuposto'],['priceTo','Preço aplicável até / pressuposto (vazio se sem termo fixado)'],['documentRef','Documento da transmissão / referência da previsão'],['documentDate','Data do documento / prevista'],['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={['operationDate','priceFrom','priceTo','documentDate'].includes(field)?'date':field==='period'?'month':'text'} value={row[field]} onChange={e=>change(row.id,{[field]:e.target.value})}/></label>)}
{rule&&<label>{row.treatment==='fuel_tax_included'?'Contraprestação sem IVA,com TC incluída (moeda indicada)':'Contraprestação sem IVA,já sem TC (moeda indicada)'}<input className="block rounded border p-2" value={row.consideration} onChange={e=>change(row.id,{consideration:e.target.value})}/></label>}
{row.treatment==='fuel_tax_included'&&<><label>TC incluída nesta contraprestação (moeda indicada)<input className="block rounded border p-2" value={row.fuelTax} onChange={e=>change(row.id,{fuelTax:e.target.value})}/></label><label>Referência da TC incluída / pressuposto<input className="block rounded border p-2" value={row.fuelTaxRef} onChange={e=>change(row.id,{fuelTaxRef:e.target.value})}/></label></>}
</div>
<p>Mudar o tratamento conserva os montantes e documentos,mas exige rever se a TC ainda está incluída. Os valores ocultos e as versões anteriores mantêm-se.</p>
{rule?<fieldset><legend>Condições próprias desta transmissão</legend>{fuelBaseConditions.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 a composição para apresentar os montantes aplicáveis;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(recordFuelBases(draft,book));}catch(cause){setError(String(cause));}}}>Determinar bases de combustíveis e guardar versão</button>}
{book.result&&<><p role="status">{fuelBaseCurrent(draft,book)?'Bases de combustíveis correspondentes às entradas guardadas.':'Entradas alteradas;bases de combustíveis 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>{fuelBaseReportRows(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>;
}