Preserva classificacao contabilistica aceite e bases locais
Regista aceitacao funcional do primeiro incremento PGC-NIRF e preserva as dependencias documentais e tecnicas existentes. A validacao do calculo fiscal continua separada e pendente. Sem credenciais, bases operacionais ou publicacao.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import DocumentPreview from './DocumentPreview.jsx';
|
||||
|
||||
export const serviceAreas = { clients: 'Clientes', services: 'Serviços', service_drafts: 'Prestações em rascunho', billing_drafts: 'Rascunhos de facturação' };
|
||||
const actions = { view: 'Consultar', create: 'Criar', edit: 'Editar', manage: 'Gerir concessões' };
|
||||
@@ -16,6 +17,7 @@ export default function ServicesWorkspace({ area, context, can, api, perform, bu
|
||||
const [key, setKey] = useState(() => crypto.randomUUID());
|
||||
const [access, setAccess] = useState(false);
|
||||
const [reviewConfirmation, setReviewConfirmation] = useState(false);
|
||||
const [previewMode, setPreviewMode] = useState(null);
|
||||
const path = `/api/a/${area}`;
|
||||
|
||||
async function load() { const result = await api(path); setRecords(result.records); }
|
||||
@@ -67,6 +69,7 @@ export default function ServicesWorkspace({ area, context, can, api, perform, bu
|
||||
function changeLine(index, field, value) { setForm({ ...form, lines: form.lines.map((line, n) => n === index ? { ...line, [field]: value } : line) }); }
|
||||
|
||||
if (!allowed('view')) return <section className="panel"><h1>{serviceAreas[area]}</h1><p>Sem consulta autorizada neste contexto.</p></section>;
|
||||
if (previewMode && selected) return <DocumentPreview id={selected.id} historical={previewMode === 'history'} context={context} api={api} onClose={() => setPreviewMode(null)} />;
|
||||
return <>
|
||||
<div className="a-heading"><div><p className="eyebrow">SERVIÇOS · PREPARAÇÃO E CONFIRMAÇÃO INTERNA</p><h1>{serviceAreas[area]}</h1><p className="muted">{isDraft(area) ? `Unidade: ${context.unit?.name || 'não seleccionada'}` : 'Cadastro partilhado pelas unidades da empresa'}</p></div><div className="actions">{allowed('create') && <button className="primary" disabled={busy} onClick={() => start()}>Novo registo</button>}{allowed('manage') && <button onClick={() => { setAccess(!access); setForm(null); }}>Gerir acessos desta área</button>}</div></div>
|
||||
{error && <div role="alert" className="alert error">{error}</div>}
|
||||
@@ -91,6 +94,7 @@ export default function ServicesWorkspace({ area, context, can, api, perform, bu
|
||||
{area === 'billing_drafts' && allowed('edit') && !selected.confirmation && <button disabled={busy} onClick={() => perform(async () => { await api(`${path}/${selected.id}`, 'PATCH', { version: selected.version, reload_source: true }, context.token, key); await open(selected.id); await load(); setKey(crypto.randomUUID()); }, 'Dados da prestação reutilizados explicitamente numa nova versão do rascunho.')}>Actualizar explicitamente da prestação</button>}
|
||||
{area === 'billing_drafts' && !selected.confirmation && can('billing_drafts.confirm_internal', context.unit?.id) && <div className="a-pending"><h3>Confirmação interna</h3><p>Fixa esta versão e os dados que a sustentam. Bloqueia a edição deste rascunho. Não confirma a execução do serviço, não emite factura nem reconhece receita.</p>{reviewConfirmation ? <><p>Confirmar a versão {selected.version} neste contexto: {context.company.name} / {context.unit?.name}? Quantidades e preços devem estar completos; moeda e regras desconhecidas ficam pendentes na fotografia.</p><div className="actions"><button className="primary" disabled={busy} onClick={() => perform(async () => { await api(`/api/b1/billing-drafts/${selected.id}/confirm-internal`, 'POST', { version: selected.version }, context.token, key); await open(selected.id); await load(); setKey(crypto.randomUUID()); }, 'Confirmado internamente — sem validade fiscal')}>Confirmar internamente esta versão</button><button onClick={() => setReviewConfirmation(false)}>Voltar ao rascunho</button></div></> : <button disabled={busy} onClick={() => { setKey(crypto.randomUUID()); setReviewConfirmation(true); }}>Rever confirmação interna</button>}</div>}
|
||||
{selected.confirmation && <InternalDocument confirmation={selected.confirmation} />}
|
||||
{area === 'billing_drafts' && (selected.confirmation ? <button onClick={() => setPreviewMode('history')}>Abrir confirmação interna histórica</button> : can('issuer_documents.view') && can('client_documents.view') && can('draft_documents.view',context.unit?.id) && <button className="primary" onClick={() => setPreviewMode('draft')}>Pré-visualizar rascunho</button>)}
|
||||
</>}
|
||||
<details className="a-history"><summary>Histórico e captura durável ({selected.history?.length || 0} versões)</summary>{selected.history?.map(entry => <div key={entry.id}><strong>Versão {entry.version}</strong><p className="help">{entry.created_at} · Autor #{entry.actor_id} · Evento #{entry.event?.id} · Capturado, sem processamento contabilístico</p><details><summary>Dados preservados nesta versão</summary><pre>{JSON.stringify(entry.snapshot, null, 2)}</pre></details></div>)}</details>
|
||||
</> : <><h2>Seleccione um registo</h2><p>Os dados e o histórico aparecem aqui. As operações disponíveis dependem das suas concessões explícitas.</p></>}
|
||||
|
||||
Reference in New Issue
Block a user