Files
Investidor-V2/resources/js/components/simulation-digital.tsx
T
2026-10-25 01:27:21 +02:00

45 lines
9.7 KiB
TypeScript

import {useState} from 'react';
import {digitalBook,digitalConditions,digitalCurrent,digitalReportRows,digitalSource,digitalTreatments,newDigitalRow,recordDigital,saveDigitalBook,switchDigitalKind,switchDigitalTreatment,type DigitalBook,type DigitalRow} from '@/lib/iva-digital';
export function SimulationDigital({draft,onChange}:{draft:Record<string,unknown>;onChange:(field:string,value:string)=>void}){
const[error,setError]=useState('');let book:DigitalBook;
try{book=digitalBook(draft);}catch(e){return<p role="alert">{String(e)}</p>;}
const save=(next:DigitalBook)=>{try{onChange('modelo_a_snapshot',saveDigitalBook(draft,next));setError('');}catch(e){setError(String(e));}};
const change=(id:string,patch:Partial<DigitalRow>)=>save({...book,rows:book.rows.map(r=>r.id===id?{...r,...patch}:r)});
return<details className="space-y-3 rounded border p-3"><summary>Bens e serviços digitais — natureza, localização e obrigações</summary>
<p>Distinga o activo transmitido da funcionalidade prestada. O nome comercial, a moeda, a nacionalidade ou um servidor não determinam sozinhos o tratamento. Reutilize as referências da operação e os documentos disponíveis.</p>
<p>Localização não concede isenção nem calcula IVA ou dedução. A identificação do responsável não apresenta uma declaração nem inicia pagamento. As formalidades remetidas para regulamentação ficam assinaladas.</p>
<p><strong>Cobertura digital deste incremento:</strong> identificação da natureza, localização, responsável, rascunho, histórico e relatório. As formalidades regulamentares ainda não cotejadas — modelos da declaração e do mapa de retenções, procedimentos de entrega e pagamento — não estão automatizadas. Não representa cobertura digital integral nem calcula imposto ou dedução.</p>
<p>{digitalSource}</p>{error&&<p role="alert">{error}</p>}
<button type="button" className="underline" onClick={()=>save({...book,rows:[...book.rows,newDigitalRow(crypto.randomUUID())]})}>Acrescentar operação digital</button>
{book.rows.map(row=><details key={row.id} className="rounded border p-3"><summary>{row.description||'Operação digital por identificar'} — {row.period||'mês por indicar'}</summary><div className="grid gap-3 md:grid-cols-2">
<label>Natureza da operação digital<select value={row.kind} onChange={e=>change(row.id,switchDigitalKind(row,e.target.value))}><option value="">Por esclarecer</option><option value="goods">P130 — Transmissão de bem digital</option><option value="service">P121 — Prestação de serviço digital</option></select></label>
{row.kind&&<label>Tratamento digital<select value={row.treatment} onChange={e=>change(row.id,switchDigitalTreatment(row,e.target.value))}><option value="">Por indicar</option>{digitalTreatments.filter(t=>t.kind===row.kind).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 DigitalRow['origin']})}><option value="projected">Projectados / pressupostos</option><option value="effective">Efectivos declarados</option></select></label>
{([['description','Operação digital identificada'],['operationRef','Referência da operação / pressuposto'],['operationDate','Data da operação / prevista'],['period','Mês da operação'],['subjectRef','Objecto, direitos transmitidos ou funcionalidade prestada'],['natureRef','Fundamento da distinção bem/serviço e natureza digital'],['useRef','Destinatário e utilização / pressuposto'],['documentRef','Documento existente / referência da previsão'],['documentDate','Data do documento / prevista'],['scope','Âmbito: operação, bens/serviços, período e condições'],['evidence','Factos disponíveis / pressupostos expressos'],['buyerPlace','Estabelecimento ou domicílio do adquirente'],['buyerRef','Referência do estabelecimento ou domicílio adquirente']] as const).map(([field,label])=><label key={field}>{label}<input type={['operationDate','documentDate'].includes(field)?'date':field==='period'?'month':'text'} value={row[field]} onChange={e=>change(row.id,{[field]:e.target.value})}/></label>)}
<label>País do estabelecimento ou domicílio adquirente<select value={row.buyerCountry} onChange={e=>change(row.id,{buyerCountry:e.target.value})}><option value="">Por esclarecer</option><option value="MZ">Moçambique</option><option value="foreign">Estrangeiro</option></select></label>
{row.buyerCountry!=='foreign'&&<>
<label>Sede, EP ou domicílio a partir do qual o fornecedor opera<input value={row.providerPlace} onChange={e=>change(row.id,{providerPlace:e.target.value})}/></label><label>Referência desse estabelecimento fornecedor<input value={row.providerRef} onChange={e=>change(row.id,{providerRef:e.target.value})}/></label>
<label>País do estabelecimento fornecedor<select value={row.providerCountry} onChange={e=>change(row.id,{providerCountry:e.target.value})}><option value="">Por esclarecer</option><option value="MZ">Moçambique</option><option value="foreign">Estrangeiro</option></select></label>
</>}
{row.buyerCountry==='MZ'&&row.providerCountry==='foreign'&&<>
<label>Adquirente sujeito passivo nacional —26(4)<select value={row.buyerTaxable} onChange={e=>change(row.id,{buyerTaxable:e.target.value})}><option value="">Por esclarecer</option><option value="yes">Sim</option><option value="no">Não</option></select></label>
<label>Fundamento da qualidade fiscal do adquirente<input value={row.buyerTaxRef} onChange={e=>change(row.id,{buyerTaxRef:e.target.value})}/></label><p>A qualidade fiscal serve para identificar o responsável; a sua falta não transforma a localização nacional em operação estrangeira.</p>
{row.buyerTaxable==='no'&&<>
<label>Fornecedor não residente sujeito passivo<select value={row.providerTaxable} onChange={e=>change(row.id,{providerTaxable:e.target.value})}><option value="">Por esclarecer</option><option value="yes">Sim</option><option value="no">Não</option></select></label><label>Fundamento da qualidade fiscal do fornecedor não residente<input value={row.providerTaxRef} onChange={e=>change(row.id,{providerTaxRef:e.target.value})}/></label>
<label>Representante residente nomeado —26(1)<select value={row.representative} onChange={e=>change(row.id,{representative:e.target.value})}><option value="">Por esclarecer</option><option value="yes">Sim</option><option value="no">Não</option></select></label>
{row.representative==='yes'&&<><label>Representante e referência da procuração/poderes<input value={row.representativeRef} onChange={e=>change(row.id,{representativeRef:e.target.value})}/></label><label>Nomeação comunicada à contraparte antes da operação —26(2)<select value={row.communicationPrior} onChange={e=>change(row.id,{communicationPrior:e.target.value})}><option value="">Por esclarecer</option><option value="yes">Sim</option><option value="no">Não</option></select></label><label>Referência da comunicação<input value={row.communicationRef} onChange={e=>change(row.id,{communicationRef:e.target.value})}/></label></>}
{row.representative==='no'&&<><label>Aquisição no exercício de actividade comercial, industrial ou profissional —26(3)<select value={row.businessUse} onChange={e=>change(row.id,{businessUse:e.target.value})}><option value="">Por esclarecer</option><option value="yes">Sim</option><option value="no">Não</option></select></label><label>Referência dessa actividade e aquisição<input value={row.businessRef} onChange={e=>change(row.id,{businessRef:e.target.value})}/></label></>}
</>}
</>}
{row.buyerCountry==='MZ'&&row.providerCountry==='MZ'&&<>
<label>Fornecedor sujeito passivo nacional<select value={row.providerTaxable} onChange={e=>change(row.id,{providerTaxable:e.target.value})}><option value="">Por esclarecer</option><option value="yes">Sim</option><option value="no">Não</option></select></label><label>Fundamento da qualidade fiscal do fornecedor<input value={row.providerTaxRef} onChange={e=>change(row.id,{providerTaxRef:e.target.value})}/></label>
{row.kind==='goods'&&<><label>Local do bem na colocação à disposição —6(1)<select value={row.goodsPlace} onChange={e=>change(row.id,{goodsPlace:e.target.value})}><option value="">Por demonstrar</option><option value="MZ">Moçambique, segundo fundamento identificado</option><option value="foreign">Estrangeiro, segundo fundamento identificado</option></select></label><label>Fundamento do local do bem digital — sem inferência pelo servidor<input value={row.goodsPlaceRef} onChange={e=>change(row.id,{goodsPlaceRef:e.target.value})}/></label></>}
</>}
</div><fieldset><legend>Factos próprios da natureza escolhida</legend>{digitalConditions(row.kind).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 esclarecer</option><option value="yes">Sim</option><option value="no">Não</option></select></label>)}</fieldset>
<p>Mudar natureza ou tratamento conserva referências e campos ocultos; reveja as confirmações próprias. Os dados não são copiados de outra oportunidade.</p></details>)}
{!!book.rows.length&&<button type="button" onClick={()=>{try{save(recordDigital(draft,book));}catch(e){setError(String(e));}}}>Classificar operações digitais e guardar versão</button>}
{book.result&&<><p role="status">{digitalCurrent(draft,book)?'Resultados correspondem às entradas guardadas.':'Entradas alteradas; resultados históricos conservados. Reveja o delta afectado.'} {book.history?.length??0} versões anteriores. Sem cálculo de IVA ou dedução.</p><dl>{digitalReportRows(draft).map(([,label,value,origin],i)=><div key={i}><dt>{label}</dt><dd>{value}<small className="block">{origin}</small></dd></div>)}</dl></>}
</details>;
}