import React,{useEffect,useMemo,useState} from 'react'; import {WorkshopStockOperation} from './workshop-stock-operation.js'; import {minorAmount} from './ledger-report-view.js'; export const dueLabels={prepared:'Preparado — por rever',approved:'Aprovado',refused:'Recusado'}; export function DueFacts({data}){return <>
{data.basis.document.number} · {data.basis.document.supplier_name}
Saldo actual {minorAmount(String(data.basis.position.balance_minor))} {data.basis.position.currency}. Vencimento original: {data.basis.position.due_on??'Desconhecido'}.
Condição administrativa revista: {data.reviewed_terms?.due_on??'Desconhecida'} · {data.days_overdue===null?'Atraso indeterminado':data.days_overdue+' dia(s) de atraso'} à referência {data.reference_on}.
{data.reviewed_terms&&Evidência: {data.reviewed_terms.evidence}
}>;} export default function PayableDueWorkspace({row,api,context,onClose}){ const[reference,setReference]=useState(''),[query,setQuery]=useState(null),[data,setData]=useState(null),[form,setForm]=useState(null),[preview,setPreview]=useState(null),[error,setError]=useState(''),[notice,setNotice]=useState(''),[busy,setBusy]=useState(false),[receiptKey,setReceiptKey]=useState(''),[receipt,setReceipt]=useState(null); const operation=useMemo(()=>new WorkshopStockOperation(api),[context.token]);const locked=busy||operation.uncertain; useEffect(()=>{if(!query)return;let active=true;setBusy(true);setError('');api('/api/finance/payable-due?'+new URLSearchParams({obligation_id:row.obligation_id,...query})).then(v=>{if(active)setData(v);}).catch(e=>{if(active){setError(e.message);setData(null);}}).finally(()=>{if(active)setBusy(false);});return()=>{active=false;};},[context.token,row.obligation_id,query]); function start(action){setError('');setReceipt(null);setPreview(null);setForm({action,obligation_id:row.obligation_id,version:data.basis.version,reason:'',data:action==='prepare'?{due_on:'',evidence:''}:{decision:''},unknown:false});} async function previewForm(e){e.preventDefault();setBusy(true);setError('');try{const{unknown,...input}=form;if(input.action==='prepare')input.data={...input.data,due_on:unknown?null:input.data.due_on};const key=crypto.randomUUID();const out=await api('/api/finance/payable-due/preview','POST',input,undefined,key);setPreview({...out,key});}catch(e){setError(e.message);}finally{setBusy(false);}} async function confirm(retry=false){setBusy(true);setError('');try{const out=retry?await operation.retry():await operation.send('/api/finance/payable-due/confirm',{preview:preview.preview},preview.key);setReceiptKey(preview.key);setNotice('Versão '+out.version+': '+dueLabels[out.state]+(out.replayed?' · recibo recuperado':''));setForm(null);setPreview(null);setQuery(q=>({...q,page:1}));}catch(e){setError(e.message);if(!operation.uncertain)setPreview(null);}finally{setBusy(false);}} async function recoverReceipt(){setBusy(true);setError('');try{setReceipt(await api('/api/finance/payable-due/receipts/'+encodeURIComponent(receiptKey)));}catch(e){setError(e.message);}finally{setBusy(false);}} returnDocumento escolhido: {row.reference}. Condição individual revista, separada da factura e do livro monetário. Não cria pagamento, juros ou lançamento.
{error&&{error}
}{notice&&{notice}
} {data&&<>{data.notice}
Versão actual {data.basis.version} · {dueLabels[data.basis.last?.state]??'Sem preparação'}.
{data.capabilities.prepare&&}{data.capabilities.review&&data.basis.last?.state==='prepared'&&}| Versão / estado | Condição / evidência | Autor / data / fundamento |
|---|---|---|
| {v.version} · {dueLabels[v.state]} | {v.data.due_on??'Desconhecido'}{v.data.evidence} | QA{v.host_actor_id} · {v.created_at}{v.reason} |
Página {data.history.current_page} de {data.history.last_page}, {data.history.total} evento(s).
>} {form&&} {preview&&Antes: v{preview.impact.before.version}, condição revista {preview.impact.before.reviewed_terms?.due_on??'Desconhecida'}. Depois: v{preview.impact.after.version}, {dueLabels[preview.impact.after.state]}, condição revista {preview.impact.after.reviewed_terms?.due_on??'Desconhecida'}.
Proposta: {preview.impact.after.proposal.due_on??'Desconhecido'} · {preview.impact.after.proposal.evidence}
Saldo mantém {minorAmount(preview.impact.balance_minor)} {preview.impact.currency}; zero pagamentos e zero lançamentos. Fundamento: {form.reason}.
Chave de recuperação: {preview.key}
Resultado incerto. Conserve esta decisão e a chave; não prepare outra operação.
>}Recibo histórico v{receipt.result.version} · {dueLabels[receipt.result.state]} · {receipt.created_at} · {receipt.reason}. Nenhuma operação executada nesta consulta.
}