Files
Investidor-V2/resources/js/components/simulation-service-location.tsx
T

43 lines
7.6 KiB
TypeScript

import {useState} from 'react';
import {newServiceLocation,switchServiceTreatment,serviceLocationBook,serviceLocationConditions,ownServiceConditions,serviceLocationCurrent,serviceLocationReportRows,serviceLocationSource,serviceLocationTreatments,recordServiceLocations,saveServiceLocationBook,type ServiceLocationBook,type ServiceLocationRow} from '@/lib/iva-service-location';
export function SimulationServiceLocation({draft,onChange}:{draft:Record<string,unknown>;onChange:(field:string,value:string)=>void}){
const[error,setError]=useState('');let book:ServiceLocationBook;
try{book=serviceLocationBook(draft);}catch(cause){return<p role="alert">{String(cause)}</p>;}
const save=(next:ServiceLocationBook)=>{try{onChange('modelo_a_snapshot',saveServiceLocationBook(draft,next));setError('');}catch(cause){setError(String(cause));}};
const change=(id:string,patch:Partial<ServiceLocationRow>)=>save({...book,rows:book.rows.map(row=>row.id===id?{...row,...patch}:row)});
return<details className="space-y-3 rounded border p-3">
<summary>Localização — serviços, imóveis, trabalhos, actividades e transporte</summary>
<p>Oportunidade: {String(draft.context_opportunity||'entrada geral')}. Regra geral:ponto de estabelecimento do prestador a partir do qual o serviço é prestado. Imóveis,execução total/essencial em bens móveis e actividades materiais têm percursos próprios,independentemente da sede do prestador.</p>
<p>Conferir primeiro a natureza e as regras especiais. Endereço/nacionalidade do cliente não substituem os factos relevantes. Digital e outros6(7)/(8)seguem os seus percursos. Classificação territorial não concede isenção nem calcula IVA.</p>
<p>{serviceLocationSource}</p>{error&&<p role="alert">{error}</p>}
<button type="button" className="underline" onClick={()=>save({...book,rows:[...book.rows,newServiceLocation(crypto.randomUUID())]})}>Acrescentar localização de serviç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 de localização do serviço<select className="block rounded border p-2" value={row.treatment} onChange={e=>change(row.id,switchServiceTreatment(row,e.target.value))}><option value="">Por indicar</option>{serviceLocationTreatments.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 ServiceLocationRow['origin']})}><option value="projected">Projectados / pressupostos</option><option value="effective">Efectivos declarados</option></select></label>
{([['description','Serviço identificado'],['operationRef','Referência da operação / pressuposto'],['operationDate','Data do serviço / prevista'],['period','Mês do serviço'],['documentRef','Documento da operação / referência da previsão'],['documentDate','Data do documento / prevista'],['scope','Âmbito: serviço, operação, período e condições'],['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==='transport_service'?<>
<p>Uma linha por trajecto;ida e volta separadas. Use a mesma unidade nas duas distâncias. Partida e chegada nacionais incluem percurso fora do país6(6).</p>
{([['routeRef','Trajecto e referência / pressuposto'],['totalDistance','Distância total'],['nationalDistance','Distância fisicamente nacional']] as const).map(([field,label])=><label key={field}>{label}<input className="block rounded border p-2" value={row[field]} onChange={e=>change(row.id,{[field]:e.target.value})}/></label>)}
{([['departure','País do ponto de partida'],['arrival','País do ponto de chegada']] as const).map(([field,label])=><label key={field}>{label}<select className="block rounded border p-2" value={row[field]} onChange={e=>change(row.id,{[field]:e.target.value})}><option value="">Por indicar</option><option value="MZ">Moçambique</option><option value="foreign">Estrangeiro</option></select></label>)}
</>:row.treatment==='general_service'?<>
<label>Estabelecimento do prestador a partir do qual o serviço é prestado<input className="block rounded border p-2" value={row.providerPlace} onChange={e=>change(row.id,{providerPlace:e.target.value})}/></label>
<label>País desse estabelecimento<select className="block rounded border p-2" value={row.providerCountry} onChange={e=>change(row.id,{providerCountry:e.target.value})}><option value="">Por indicar</option><option value="MZ">Moçambique</option><option value="foreign">Estrangeiro</option></select></label>
<label>Referência do estabelecimento prestador / pressuposto<input className="block rounded border p-2" value={row.providerRef} onChange={e=>change(row.id,{providerRef:e.target.value})}/></label>
</>:row.treatment&&<>
<label>{row.treatment==='immovable_service'?'Local do imóvel':row.treatment==='movable_work'?'Local de execução total ou essencial':'Local material da actividade ou serviço acessório'}<input className="block rounded border p-2" value={row.servicePlace} onChange={e=>change(row.id,{servicePlace:e.target.value})}/></label>
<label>Situação do local relevante<select className="block rounded border p-2" value={row.placeCountry} onChange={e=>change(row.id,{placeCountry:e.target.value})}><option value="">Por indicar</option><option value="MZ">Moçambique</option><option value="foreign">Estrangeiro</option></select></label>
<label>Referência da localização / pressuposto<input className="block rounded border p-2" value={row.placeRef} onChange={e=>change(row.id,{placeRef:e.target.value})}/></label>
<label>Imóvel, bens ou actividade e relação do serviço<input className="block rounded border p-2" value={row.subjectRef} onChange={e=>change(row.id,{subjectRef:e.target.value})}/></label>
</>}
</div>
<p>Mudar percurso conserva os locais e referências,mas exige rever os factos próprios. Campos sem aplicação ficam ocultos e conservados.</p>
<fieldset><legend>Factos próprios deste percurso</legend>{[...serviceLocationConditions,...ownServiceConditions(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(recordServiceLocations(draft,book));}catch(cause){setError(String(cause));}}}>Classificar localização e guardar versão</button>}
{book.result&&<><p role="status">{serviceLocationCurrent(draft,book)?'Localizações correspondentes às entradas guardadas.':'Entradas alteradas;localizações históricas conservadas. Reveja e classifique novamente.'} {book.history?.length??0} versões anteriores. Classificação não determina isenção,IVA ou campo11.</p><dl>{serviceLocationReportRows(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>;
}