import React, {useEffect,useRef,useState} from 'react';
const decisionLabel={approved:'Validado',refused:'Recusado'};
const money=v=>v===null?'Pendente':`${v} MZN`;
export default function DirectCostsWorkspace({context,can,api,busy}) {
const [data,setData]=useState(null),[error,setError]=useState(''),[working,setWorking]=useState(false),[orderId,setOrderId]=useState('');
const [selection,setSelection]=useState({}),[sourceId,setSourceId]=useState('');const retry=useRef(null);
const allowed=r=>can(`direct_costs.${r}`,context.unit?.id??null);
const load=async()=>{const d=await api('/api/direct-costs');setData(d);return d;};
useEffect(()=>{setSelection({});load().catch(e=>setError(e.message));},[context.token]);
const order=data?.orders.find(o=>String(o.id)===orderId)??data?.orders[0];
async function send(path,input){setWorking(true);setError('');const signature=JSON.stringify([path,input]);if(retry.current?.signature!==signature)retry.current={signature,key:crypto.randomUUID()};
try{await api(path,'POST',input,context.token,retry.current.key);retry.current=null;await load();}catch(e){setError(e.message);}finally{setWorking(false);}}
const disabled=busy||working;
const latest=order?.calculations.at(-1);
const source=order?.sources.find(s=>String(s.id)===sourceId)??order?.sources[0];
const decide=(kind,row,decision,reason)=>send(`/api/direct-costs/orders/${order.id}/decisions`,{kind,id:row.id,version:row.version,decision,reason});
return ENSAIO DE CUSTO DIRECTO
Custos directos da ordem ENSAIO — SEM UTILIZAÇÃO OPERACIONAL. Custo directo conhecido; não é custo completo ou margem. Sem stock, IVA, lançamentos ou facturação.
{error&&{error}
}{!data?A carregar…
:data.blocked?O custeio permanece bloqueado nesta instância. Use apenas a demonstração isolada.
:<>
load().catch(e=>setError(e.message))}>Actualizar versões explicitamente
Ordem de teste{setOrderId(e.target.value);setSelection({});setSourceId('');}}>{data.orders.map(o=>{o.reference} · #{o.id} )}
{!order?Sem ordens no âmbito autorizado.
:<>
Origens técnicas verificadas Referências aos apontamentos existentes. A validação de custos não modifica nem verifica a execução técnica.
{order.sources.map(s=>#{s.id} v{s.version} · {s.origin} · {s.quantity} {s.unit} · {s.kind==='time'?'Trabalho efectivo':'Consumo efectivo'} )}
{allowed('prepare')&&source&&}
Taxas e decisões {order.rates.map(r=>#{r.id} · {r.identifier} v{r.version} Origem #{r.entry_id} v{r.entry_version} · {r.amount} {r.currency}/{r.unit}
{r.evidence}
{r.current?'Última versão da taxa':'Versão anterior'} · {r.decision?decisionLabel[r.decision.decision]:'Aguarda validação'}{r.decision&&` — ${r.decision.reason}`}
{allowed('validate')&&r.current&&!r.decision&&decide('rate',r,d,reason)}/>} )}
{allowed('prepare')&&}
Histórico de cálculos {order.calculations.map(c=>Cálculo #{c.id} · v{c.version} {c.current?'Dependências actuais':'DESACTUALIZADO / HISTÓRICO — não usar como actual'} · {c.decision?decisionLabel[c.decision.decision]:'Aguarda validação'}{c.decision&&` — ${c.decision.reason}`}
{c.snapshot.label}
Origem / versão Quantidade exacta Taxa / versão Custo exacto {c.snapshot.lines.map(l=>#{l.entry_id} v{l.entry_version} {l.quantity} {l.source_unit}{l.kind==='time'&&` ÷ 60 = ${l.cost_quantity_exact} H`} {l.rate_id===null?'Em falta':`#${l.rate_id} v${l.rate_version} · ${l.rate_amount} MZN/${l.rate_unit}`} {money(l.cost_exact)} )}
Subtotal directo conhecido: {money(c.snapshot.known_subtotal_exact)}
{c.snapshot.incomplete?'TOTAL INCOMPLETO — taxas em falta':'Perímetro directo seleccionado valorizado; custo completo não apurado.'}
{c.snapshot.pending.map(p=>{p} )} {c.snapshot.policy} · {c.snapshot.scope} {allowed('validate')&&c.current&&!c.decision&&decide('calculation',c,d,reason)}/>} )}
> }> } ;
}
function DecisionForm({disabled,onDecision}) {return
;}