;}
export default function RemunerationsWorkspace({api,context}){
const[query,setQuery]=useState({kind:'worker',page:1,per_page:25}),[filters,setFilters]=useState({search:'',period:'',state:''}),[data,setData]=useState(null),[selected,setSelected]=useState(null),[form,setForm]=useState(null),[preview,setPreview]=useState(null),[busy,setBusy]=useState(false),[error,setError]=useState(''),[notice,setNotice]=useState(''),[receiptKey,setReceiptKey]=useState(''),[receipt,setReceipt]=useState(null);
const operation=useMemo(()=>new WorkshopStockOperation(api),[context.token]),mounted=useRef(true),generation=useRef(context.token);generation.current=context.token;useEffect(()=>{mounted.current=true;return()=>{mounted.current=false;};},[context.token]);const locked=busy||operation.uncertain,protectedForm=locked||Boolean(form);
useEffect(()=>{let active=true;setBusy(true);setData(null);setError('');api('/api/remunerations?'+qs(query)).then(d=>{if(active)setData(checkedRemunerations(d,query));}).catch(e=>{if(active)setError(e.message);}).finally(()=>{if(active)setBusy(false);});return()=>{active=false;};},[query,context.token]);
function start(operationName='establish',review=false,newRecord=false){const row=newRecord?null:selected,source=row?.effective?.data.input??row?.data.input,kind=query.kind;const defaults=kind==='worker'?{code:'QA-',status:'active'}:kind==='rules'?{label:'',valid_from:'',valid_to:'',worker_rate:'',employer_rate:'',retention_rate:'',source:''}:{worker_key:'',rules_key:'',period:'',gross:''};setPreview(null);setError('');setForm({kind,action:review?'review':'prepare',record_key:row?.record_key??crypto.randomUUID(),version:row?.version??0,reason:'',data:review?{decision:''}:{...(source??defaults),operation:operationName}});}
const change=(key,value)=>{setPreview(null);setForm(f=>({...f,data:{...f.data,[key]:value,...(key==='worker_key'&&f.data.contract_key?{contract_key:''}:{})}}));};
async function prepare(e){e.preventDefault();setBusy(true);setError('');try{const input={...form,data:{...form.data}};if(!input.data.contract_key)delete input.data.contract_key;if(input.kind==='rules'&&input.action==='prepare')for(const k of['worker_rate','employer_rate','retention_rate'])if(input.data[k]==='')input.data[k]=null;const key=crypto.randomUUID(),p=await api('/api/remunerations/preview','POST',input,undefined,key);setPreview({...p,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/remunerations/confirm',{preview:preview.preview},preview.key);setReceiptKey(preview.key);setNotice('Decisão v'+out.version+' · '+states[out.state]+(out.replayed?' · recibo recuperado':''));setSelected(null);setForm(null);setPreview(null);setQuery(q=>({...q,page:1}));}catch(e){setError(e.message);if(!operation.uncertain)setPreview(null);}finally{setBusy(false);}}
async function download(row){const token=context.token;setBusy(true);setError('');try{const out=await remunerationDownload({id:row.id,token,sha256:row.data.artifact_sha256,isCurrent:()=>mounted.current&&generation.current===token});const url=URL.createObjectURL(new Blob([out.bytes],{type:'text/csv;charset=utf-8'})),a=document.createElement('a');a.href=url;a.download='sgf-remuneracao-interna-QA-v'+row.version+'.csv';a.click();setTimeout(()=>URL.revokeObjectURL(url),1000);}catch(e){if(mounted.current&&generation.current===token)setError(e.message);}finally{if(mounted.current&&generation.current===token)setBusy(false);}}
async function recover(){setBusy(true);setError('');try{setReceipt(await api('/api/remunerations/receipts/'+encodeURIComponent(receiptKey)));}catch(e){setError(e.message);}finally{setBusy(false);}}
const textInput=(key,label,type='text',extra={})=>;
return
RECURSOS HUMANOS
Remunerações internas QA
Área autónoma, com acessos próprios. Cadastro e regras fictícios, processamento e revisão distinta. Sem salário/dívida/pagamento/lançamento, recibo legal ou submissão. Contratos, assiduidade e férias estão na função própria de RH. A conformidade legal continua pendente.
Somente aprovados activos desta página: {data.page_totals.approved_active_on_page}; bruto{remunerationMoney(data.page_totals.gross_cents)}, líquido{remunerationMoney(data.page_totals.net_cents)}, custo{remunerationMoney(data.page_totals.employer_cost_cents)}. Não são totais do universo nem salários pagos.
}>}
{selected&&
Registo escolhido · v{selected.version}
{JSON.stringify(selected.data.input,null,2)}
Estado anterior: v{selected.impact.before.version} · {selected.impact.before.state??'Sem registo'}. Estado posterior: v{selected.impact.after.version} · {states[selected.state]}.
Antes v{preview.impact.before.version}, {preview.impact.before.state??'Sem registo'}; depois v{preview.impact.after.version}, {states[preview.impact.after.state]} · {preview.impact.after.proposal.status}.