34 lines
6.4 KiB
TypeScript
34 lines
6.4 KiB
TypeScript
import {useState} from 'react';
|
||
import {newRegularization,regularizationBook,regularizationSources,saveRegularizationBook,recordRegularizations,regularizationReportRows,frozenAssetRows,type RegularizationEvent,type RegularizationBook} from '@/lib/iva-regularizations';
|
||
export function AcquisitionRegularizations({draft,onChange}:{draft:Record<string,unknown>;onChange:(field:string,value:string)=>void}){
|
||
const[error,setError]=useState('');let b:RegularizationBook;
|
||
try{b=regularizationBook(draft);}catch(cause){return<p role="alert">{String(cause)}</p>;}
|
||
const save=(next:RegularizationBook)=>{try{onChange('modelo_a_snapshot',saveRegularizationBook(draft,next));setError('');}catch(cause){setError(String(cause));}};
|
||
const change=(id:string,patch:Partial<RegularizationEvent>)=>save({...b,events:b.events.map(e=>e.id===id?{...e,...patch}:e)});
|
||
const sources=regularizationSources(draft);
|
||
const add=(kind:RegularizationEvent['kind'])=>save({...b,events:[...b.events,newRegularization(crypto.randomUUID(),kind,sources.at(-1)??null)]});
|
||
const labels={scope:'As parcelas e o âmbito correspondem ao evento,sem estender o direito a outros bens/operações',recorded:'O valor original foi deduzido ou é pressuposto explicitamente assumido nesta simulação',annual:'Bases finais do ano completo22(4),semIVA,incluindo operações fora de campo',exclusions:'Excluí vendas de activo usado e operações imobiliárias/financeiras acessórias22(5)',supplierCorrection:'O fornecedor anulou/reduziu a operação e emitiu o documento rectificativo',rightUnchanged:'O documento conserva o âmbito e as condições de dedução;sem alteração de direito'};
|
||
return<details className="rounded border p-3"><summary>E — activos e regularizações por evento</summary>
|
||
<p>Reutiliza resultados congelados de D e documentos existentes. O acerto anual usa o IVA elegível antes de D, já limitado por C, e compara com o deduzido. Uma rectificação da compra tem documento e prazo próprios. Guardar E não altera as deduções originais; depois actualize expressamente o apuramento parcial para conferir F.</p>
|
||
<p>18.º(6) com afectação mista continua pendente. Não existe regularização plurianual genérica de activos,correcção de erros ou incobráveis automatizada neste percurso. Submissão fiscal fora do InvesteMoz;19–27/restituição em L3.</p>
|
||
{error&&<p role="alert">{error}</p>}
|
||
<button type="button" onClick={()=>add('annual')}>Preparar acerto anual do pro rata</button>{' '}
|
||
<button type="button" onClick={()=>add('purchase_correction')}>Preparar rectificação da dedução pelo adquirente</button>
|
||
{b.events.map((e,index)=><fieldset className="rounded border p-3" key={e.id}><legend>{index+1}. {e.kind==='annual'?'Acerto anual22(6)':'Rectificação51(4)'}</legend>
|
||
<label>Resultado original congelado<select value={sources.findIndex(s=>JSON.stringify(s)===JSON.stringify(e.source))} onChange={event=>{const source=sources[Number(event.target.value)];if(source)change(e.id,{source:structuredClone(source),rowIds:source.inputs.filter(r=>e.kind!=='annual'||r.d?.method==='pro_rata').map(r=>r.id)});}}><option value={-1}>Seleccione uma versão</option>{sources.map((s,i)=><option key={i} value={i}>Revisão{s.revision} — {s.calculatedAt}</option>)}</select></label>
|
||
<p>Escolher outra versão adopta expressamente as parcelas dessa versão,conservando os outros dados do evento. Desmarque parcelas fora do âmbito;não pode regularizar a mesma aquisição duas vezes.</p>
|
||
{e.source?.inputs.map(r=><label className="block" key={r.id}><input type="checkbox" checked={e.rowIds.includes(r.id)} onChange={event=>change(e.id,{rowIds:event.target.checked?[...e.rowIds,r.id]:e.rowIds.filter(id=>id!==r.id)})}/>{r.description||r.id} — {r.documentRef} — {r.period} — {r.origin==='projected'?'Pressuposto de simulação':'Efectivo declarado'}</label>)}
|
||
<label>Período da regularização<input type="month" value={e.period} min="2026-01" max="2026-12" onChange={v=>change(e.id,{period:v.target.value})}/></label>
|
||
<label>Documento/fonte do evento<input value={e.reference} onChange={v=>change(e.id,{reference:v.target.value})}/></label>
|
||
<label>Motivo e âmbito do evento<input value={e.reason} onChange={v=>change(e.id,{reason:v.target.value})}/></label>
|
||
{e.kind==='annual'?<><label>Operações anuais finais com direito — sem IVA (MZN)<input value={e.numerator} onChange={v=>change(e.id,{numerator:v.target.value})}/></label><label>Total anual final22(4–5) — sem IVA (MZN)<input value={e.denominator} onChange={v=>change(e.id,{denominator:v.target.value})}/></label></>:<><label>Data de recepção do documento rectificativo<input type="date" value={e.receivedDate} onChange={v=>change(e.id,{receivedDate:v.target.value})}/></label><label>Dedução corrigida documentada (MZN)<input value={e.correctedDeductible} onChange={v=>change(e.id,{correctedDeductible:v.target.value})}/></label></>}
|
||
{Object.entries(labels).filter(([k])=>['scope','recorded',...(e.kind==='annual'?['annual','exclusions']:['supplierCorrection','rightUnchanged'])].includes(k)).map(([k,label])=><label className="block" key={k}>{label}<select value={e.facts[k]??''} onChange={v=>change(e.id,{facts:{...e.facts,[k]:v.target.value as ''|'yes'|'no'}})}><option value="">Por confirmar</option><option value="yes">Sim</option><option value="no">Não</option></select></label>)}
|
||
<button type="button" onClick={()=>save({...b,events:b.events.filter(row=>row.id!==e.id)})}>Remover evento em preparação (histórico conservado)</button>
|
||
</fieldset>)}
|
||
{[...new Set(b.events.map(e=>e.period))].filter(Boolean).map(period=><label className="block" key={period}><input type="checkbox" checked={b.completePeriods.includes(period)} onChange={e=>save({...b,completePeriods:e.target.checked?[...b.completePeriods,period]:b.completePeriods.filter(p=>p!==period)})}/>Reconciliei todas as regularizações deste período — {period};os outros motivos não automatizados foram conferidos.</label>)}
|
||
<p>Quando existirem eventos E, retire as declarações «Sem operações» nos campos12/13 desse período. Uma cobertura incompleta mantém os totais afectados indeterminados.</p>
|
||
<button type="button" onClick={()=>{try{save(recordRegularizations(draft,b));}catch(cause){setError(String(cause));}}}>Calcular e guardar regularizações E</button>
|
||
{[...regularizationReportRows(draft),...frozenAssetRows(draft)].map(([,label,value,source],i)=><p key={i}><strong>{label}</strong>: {value}<small className="block">{source}</small></p>)}
|
||
</details>;
|
||
}
|