commit melhorias sgf
This commit is contained in:
@@ -10,7 +10,7 @@ export default function ServiceInvoiceWorkspace({api,context,can,perform,busy})
|
||||
const unit=context.unit?.id;
|
||||
const fields=kind==='series'?{code:'Código da série de teste (TEST-...)',first_number:'Primeiro número de teste',valid_from:'Vigência desde',valid_until:'Vigência até (opcional)',evidence:'Fundamento da configuração sintética'}:{draft_id:'Rascunho existente',draft_version:'Versão do rascunho',preparation_version:'Versão da preparação',profile_proposal_id:'Proposta do perfil fiscal',valid_from:'Vigência desde',valid_until:'Vigência até (opcional)',period_start:'Início da cobertura',period_end:'Fim da cobertura',issue_window_start:'Janela fundamentada de emissão desde',issue_window_end:'Janela fundamentada até',readiness_basis:'Fundamento da prontidão documental e representação',evidence:'Evidências e pressupostos sintéticos'};
|
||||
async function propose(e){e.preventDefault();await perform(async()=>{const data={};for(const field of Object.keys(fields))if(f[field]!=='')data[field]=field.endsWith('_id')||field.endsWith('_version')||field==='first_number'?Number(f[field]):f[field];if(kind==='series')data.state=f.state;else data.event='on_issue_within_deadline';await api('/api/service-invoices/proposals','POST',{kind,identifier:kind==='series'?f.code:f.identifier,...(f.previous_id?{previous_id:Number(f.previous_id)}:{}),data});await load();},'Proposta de teste submetida para validação.');}
|
||||
return <section className="fiscal-workspace invoice-test-workspace"><p className="eyebrow">DEMONSTRAÇÃO DOCUMENTAL ISOLADA</p><h1>Facturas de teste</h1><div className="fiscal-notice"><strong>{notice}</strong><span>Emissão real bloqueada. Sem comunicação à AT, envio automático, recebimentos ou lançamentos.</span></div>{error&&<p role="alert">{error}</p>}
|
||||
return <section className="fiscal-workspace invoice-test-workspace"><p className="eyebrow">{context.single_installation?'SGF · COMERCIAL':'DEMONSTRAÇÃO DOCUMENTAL ISOLADA'}</p><h1>Facturas de teste</h1><div className="fiscal-notice"><strong>{notice}</strong><span>Emissão real bloqueada. Sem comunicação à AT ou envio automático. Recebimentos e lançamentos mantêm decisões próprias.</span></div>{error&&<p role="alert">{error}</p>}
|
||||
{!context.unit?<p>Seleccione uma unidade autorizada.</p>:!list?<p>A carregar…</p>:!list.test_enabled?<div className="panel"><h2>Emissão real indisponível</h2><p>{list.notice}</p></div>:<>
|
||||
{(can('invoice_series.propose')||can('service_fiscal.propose'))&&<details className="panel fiscal-new"><summary>Preparar série ou regra temporal de teste</summary><form onSubmit={propose}><label>Tipo<select value={kind} onChange={e=>setKind(e.target.value)}><option value="series">Configuração de série sintética</option><option value="temporal">Regra temporal prospectiva</option></select></label>{kind==='temporal'&&<label>Identificador da regra<input required value={f.identifier} onChange={e=>setF({...f,identifier:e.target.value})}/></label>}<label>Proposta anterior (apenas nova versão)<input type="number" min="1" value={f.previous_id} onChange={e=>setF({...f,previous_id:e.target.value})}/></label>{kind==='series'&&<label>Estado da série<select value={f.state} onChange={e=>setF({...f,state:e.target.value})}><option value="open">Aberta</option><option value="closed">Encerrada</option></select></label>}{Object.entries(fields).map(([field,label])=><label key={field}>{label}{['evidence','readiness_basis'].includes(field)?<textarea required rows={4} value={f[field]} onChange={e=>setF({...f,[field]:e.target.value})}/>:<input type={field.includes('window')||field.startsWith('valid_')||field.startsWith('period_')?'date':'text'} required={field!=='valid_until'} value={f[field]} onChange={e=>setF({...f,[field]:e.target.value})}/>}</label>)}<button className="primary" disabled={busy||!can(kind==='series'?'invoice_series.propose':'service_fiscal.propose')}>Submeter proposta</button></form></details>}
|
||||
<h2>Séries e regras temporais</h2>{list.proposals.map(p=><article className="fiscal-proposal" key={p.id}><div className="fiscal-card-heading"><div><p className="eyebrow">{p.kind==='series'?'SÉRIE SINTÉTICA':'REGRA TEMPORAL'}</p><h3>{p.identifier} · v{p.version}</h3><p>Proposta #{p.id} · {p.decision?.decision==='approved'?'Validada':p.decision?.decision==='refused'?'Recusada':'Aguarda validação'}</p></div></div>{p.kind==='series'?<p>Número inicial: {p.definition.first_number} · {p.definition.state==='open'?'Aberta':'Encerrada'} · Desde {p.definition.valid_from}</p>:<p>Rascunho #{p.definition.draft_id} · Emissão dentro da janela fundamentada {p.definition.issue_window_start} a {p.definition.issue_window_end}. A data efectiva só é fixada na confirmação.</p>}<p>{p.definition.evidence}</p>{p.definition.readiness_basis&&<p>{p.definition.readiness_basis}</p>}{!p.decision&&can(p.kind==='series'?'invoice_series.approve':'service_fiscal.approve')&&<div className="fiscal-review"><label>Fundamento da decisão<textarea value={reasons[p.id]||''} onChange={e=>setReasons({...reasons,[p.id]:e.target.value})}/></label><div className="actions">{['approved','refused'].map(decision=><button key={decision} className={decision==='approved'?'primary':''} disabled={busy||!reasons[p.id]} onClick={()=>perform(async()=>{await api(`/api/service-invoices/proposals/${p.id}/decision`,'POST',{version:p.version,decision,reason:reasons[p.id]});await load();},'Decisão registada apenas para a versão de teste.')}>{decision==='approved'?'Validar versão':'Recusar versão'}</button>)}</div></div>}</article>)}
|
||||
|
||||
Reference in New Issue
Block a user