import React,{useEffect,useState} from 'react';
import {billingSections,visibleBillingSections,filterBillingRows,loadBillingRows} from './billing-menu.js';
const emptyFilters={search:'',type:'',currency:'',series:'',state:'',author:'',from:'',to:''};
const value=v=>v===null||v===undefined||v===''?'Por determinar':String(v);
export function BillingDocumentList({rows,filters,onFilter,onClear,onOpen}) {
const filtered=filterBillingRows(rows,filters);
const options=field=>[...new Set(rows.map(r=>r[field]).filter(v=>v!==null&&v!==undefined&&v!==''))].sort();
return Lista de documentos
Pesquisar número, cliente ou NUIT onFilter('search',e.target.value)}/>
TipoonFilter('type',e.target.value)}>Todos os tipos disponíveis {options('type').map(t=>{t==='invoice'?'Factura de teste':'Rascunho'} )}
{['currency','series','state','author'].map(field=>{{currency:'Moeda',series:'Série',state:'Estado documental',author:'Autor (identificador registado)'}[field]}onFilter(field,e.target.value)}>Todos {options(field).map(v=>{v} )} )}
Emissão desde onFilter('from',e.target.value)}/> Emissão até onFilter('to',e.target.value)}/>
Limpar filtros {filters.from&&filters.to&&filters.from>filters.to?A data inicial deve ser anterior ou igual à data final.
:<>
{filtered.length} documento(s) nesta consulta.
Número / referência Tipo Cliente Emissão Vencimento Total Moeda Saldo por receber Estados Acções {filtered.map(r=>{r.number}{r.name&&{r.name} }{r.version&&Versão {r.version} } {r.typeLabel} {value(r.client)}{r.nuit&&NUIT {r.nuit} } {r.type==='draft'?'Não emitido':value(r.issuedDate)} {r.type==='draft'?'Não aplicável':value(r.dueDate)} {r.type==='draft'?'Provisório — por determinar':value(r.total)}{r.base!==undefined&&r.base!==null&&Base aritmética: {r.base} (não é total fiscal) } {value(r.currency)} {r.type==='draft'?'Não aplicável':'Consultar percurso financeiro'} {r.state}Pagamento: {r.payment} onOpen(r)}>Abrir )}
{!filtered.length&&Nenhum documento corresponde aos filtros nas fontes disponíveis.
}>}
Valores documentais preservados, sem recálculo. Não são somadas moedas diferentes. Ausência de saldo ou vencimento não significa zero, factura paga ou atraso. Filtros de emissão excluem rascunhos e datas desconhecidas.
;
}
export default function BillingMenuWorkspace({section,context,can,api,navigate}) {
const unit=context.unit?.id??null;
const [result,setResult]=useState(null),[loading,setLoading]=useState(false),[reload,setReload]=useState(0),[filters,setFilters]=useState(emptyFilters),[selected,setSelected]=useState(null);
const active=billingSections.find(s=>s.id===section);
useEffect(()=>{setSelected(null);},[section]);
useEffect(()=>{
let current=true;setResult(null);setSelected(null);
if(unit===null||active?.pending)return ()=>{current=false;};
setLoading(true);
loadBillingRows(api,can,unit).then(r=>{if(current){setResult(r);setLoading(false);}});
return ()=>{current=false;};
},[context.token,section,reload]);
if(!active)return null;
const newDraft=()=>navigate('billing_drafts',null,true);
return
FACTURAÇÃO
{active.label} Documentos comerciais no contexto de {context.company.name}{context.unit?` / ${context.unit.name}`:''}.
{visibleBillingSections(can,unit).map(s=>navigate(s.id)}>{s.label} )}
Demonstração — sem validade fiscal. A entrada e a consulta não habilitam emissão real. Documento, dívida e recebimento são factos distintos.
{!context.unit&&
Seleccione uma unidade Escolha uma unidade autorizada para consultar os seus documentos.
}
{active.pending?
Capacidade ainda não disponível {active.pending}
{section==='billing_receipts'&&can('service_receivables.view',unit)&&navigate('service_receivables')}>Abrir recebimentos e afectações de teste }{section==='billing_credit_notes'&&can('service_invoices.view',unit)&&navigate('service_invoice_setup')}>Consultar facturas e pedidos de correcção existentes }Este submenu identifica o âmbito previsto; não contém documentos simulados nem executa efeitos financeiros.
:context.unit&&<>
{can('billing_drafts.view',unit)&&can('billing_drafts.create',unit)&&Novo documento — preparar rascunho }{can('service_invoices.view',unit)&&navigate('service_invoice_setup')}>Séries e emissão de teste }setReload(r=>r+1)}>Actualizar lista
A criação reutiliza uma prestação existente e não emite automaticamente. Guardar rascunho, confirmar internamente, emitir em teste e receber mantêm os seus circuitos próprios.
{loading&&
A carregar documentos autorizados…
}
{result?.sources.map(s=>s.error?
{s.label}: consulta indisponível. {s.error} Use Actualizar lista para tentar novamente.
:s.notice?
{s.label}: {s.notice}
:null)}
{result&&!loading&&(result.sources.some(s=>!s.error&&!s.notice)?
section!=='service_invoices'||r.type==='invoice')} filters={filters} onFilter={(k,v)=>setFilters(f=>({...f,[k]:v}))} onClear={()=>setFilters(emptyFilters)} onOpen={r=>r.type==='draft'?navigate('billing_drafts',r.id):setSelected(r)}/>:Não há uma fonte documental disponível para esta consulta. Não é possível concluir que existam zero documentos.
)}
{selected&&{selected.number} Factura de teste — fotografia preservada, sem edição directa.
setSelected(null)}>Fechar ficha {selected.detail.document_lines.map(([kind,text],i)=>kind==='title'?{text} :kind==='section'?{text} :{text}
)}Descarregar PDF de teste Pedidos de correcção {selected.detail.corrections.length?selected.detail.corrections.map(c=>#{c.id}: {c.reason} · {c.created_at} · Pendente, sem efeito fiscal.
):Nenhum pedido registado.
}Enviar ao cliente, duplicar documentos, exportar selecções e emitir notas de crédito ainda não estão disponíveis neste menu. Não existe emissão ou rectificação em massa.
}
>}
;
}