18 lines
8.1 KiB
PHP
18 lines
8.1 KiB
PHP
@php $i=$data['industrial'];$b=$data['book'];$closed=$data['closed'];$money=fn($n)=>number_format($n/100,2,',',' ').' MZN'; @endphp
|
|
<!doctype html><html lang="pt"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Resultado industrial e diário QA</title><style>body{font:17px system-ui;background:#f3f6f5;color:#142b28;margin:0}main{max-width:1100px;margin:auto;padding:24px}section,header{background:white;border:1px solid #d5e0dc;border-radius:12px;padding:24px;margin:18px 0}article{border-top:1px solid #ddd;padding:16px 0}a{color:#125a4b}label{display:block;margin:12px 0}input,textarea,select,button{font:inherit;padding:10px;max-width:95%}textarea{display:block;width:90%}pre,code{white-space:pre-wrap;overflow-wrap:anywhere}.notice{background:#fff2cc;padding:16px}</style></head><body><main>
|
|
<header><a href="/general-ledger/workspace">Painel conjunto e fecho QA</a> · <a href="/general-ledger">Diário</a> · <a href="/general-ledger/trial-balance?from_on=2026-10-01&to_on=2026-10-31">Balancete e razão</a><h1>Lote industrial validado → Contabilidade QA</h1><p class="notice">Só ensaio sintético. Resultado seleccionado, residual separado, contas artificiais. Sem stock valorizado, folha salarial ou utilização real.</p></header><p id="error" role="alert"></p>
|
|
<section><h2>Perímetros compostos</h2>@foreach($i['lots'] as $l)<p><a href="?lot_id={{ $l->lot_id }}">Lote #{{ $l->lot_id }}</a> · {{ $l->period_key }}</p>@endforeach</section>
|
|
@if($i['facts'])@php $c=$i['facts']['conference'];$s=$c['snapshot']; @endphp<section><h2>Conferência actual do lote #{{ $i['lot_id'] }}</h2><p>{{ $c['lot']['reference'] }} · resultado #{{ $c['result']['id']??'pendente' }} / versão {{ $c['result']['version']??'—' }} · decisão {{ $c['decision']['decision']??'pendente' }}.</p><p>Material {{ $s['material_exact']??'indisponível' }} + trabalho {{ $s['labour_exact']??'indisponível' }} + CIF imputado {{ $s['allocated_exact']??'indisponível' }} MZN. Total seleccionado {{ $s['selected_total_exact']??'indisponível' }} MZN; {{ $s['good_units']??'—' }} UN; unitário {{ $s['unit_cost_exact']??'indisponível' }} MZN.</p><p>Residual {{ $s['residual_exact']??'indisponível' }} MZN separado; sem lançamento do residual.</p>@if($i['pending'])<p class="notice">{{ $i['pending'] }}</p>@endif @if($i['accounting_state']==='requires_future_correction')<p class="notice">A origem difere do resultado já lançado. Não reconhecer novamente. @if(config('industrial_ledger.correction_enabled')===true)Exige correcção explícita do par; o fecho fica impedido até à resolução.@else Correcção industrial futura por autorizar; o fecho fica impedido.@endif</p>@endif<details><summary>Entradas, taxas, critério, decisões, versões e resultado</summary><pre>{{ json_encode($i['facts'],JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE) }}</pre></details>
|
|
@if($i['source'])<p>Impacto: D QA-CUSTO-INDUSTRIAL {{ $money($i['source']['principal_minor']) }} / C QA-COMPENSACAO-INDUSTRIAL {{ $money($i['source']['principal_minor']) }}. Sem outra dívida ou movimento de stock.</p>@if(!$closed&&!$i['journal']&&$b['permissions']['prepare'])<form data-action="effect-prepare"><input type="hidden" name="effect_type" value="industry.cost.validated"><input type="hidden" name="source_id" value="{{ $i['lot_id'] }}"><input type="hidden" name="rule_key" value="QA-INDUSTRIAL"><label>Data explícita<input type="date" name="journal_on" value="2026-10-29" required></label><label>Período<input name="period_key" value="QA-2026-10" required></label><label>Fundamento<textarea name="reason" required minlength="3" maxlength="2000"></textarea></label><button>Capturar fonte e impacto sem lançar</button></form>@endif @endif</section>@endif
|
|
@if(config('industrial_ledger.correction_enabled')===true)@include('accounting.industrial-correction')@endif
|
|
<section><h2>Conferência individual do impacto</h2>@foreach($b['proposals'] as $p)@php $snap=json_decode($p->snapshot,true);$isPart=in_array($snap['source']['effect_type'],['industry.cost.reversal','industry.cost.replacement'],true);$r=collect($b['reviews'])->firstWhere('proposal_id',$p->id); @endphp<article><h3>Proposta #{{ $p->id }} · captura {{ $p->capture_version }}</h3><p>Preparador #{{ $p->prepared_by }} · {{ $p->reason }} · revisão <code>{{ $p->revision }}</code></p><ul>@foreach($snap['lines'] as $line)<li>{{ $line['account_code'] }} · D {{ $money($line['debit_minor']) }} / C {{ $money($line['credit_minor']) }}</li>@endforeach</ul><details><summary>Fotografia capturada e impacto</summary><pre>{{ $p->snapshot }}</pre></details>@if($r)<p>{{ $r->decision }} · autor #{{ $r->reviewed_by }} · {{ $r->reason }}</p>@endif
|
|
@if(!$closed&&!$isPart&&!$r&&$b['permissions']['validate']&&$p->prepared_by!==auth()->id())<form data-action="validate"><input type="hidden" name="proposal_id" value="{{ $p->id }}"><input type="hidden" name="revision" value="{{ $p->revision }}"><label>Decisão<select name="decision" required><option value="">Escolher</option><option value="approved">Aprovar versão exacta</option><option value="rejected">Recusar</option></select></label><label>Fundamento<textarea name="reason" required minlength="3" maxlength="2000"></textarea></label><button>Registar conferência independente</button></form>@endif
|
|
@if(!$closed&&!$isPart&&$r?->decision==='approved'&&!$p->journal_id&&$b['permissions']['post']&&$p->prepared_by===auth()->id())<form data-action="post"><input type="hidden" name="proposal_id" value="{{ $p->id }}"><input type="hidden" name="revision" value="{{ $p->revision }}"><label>Fundamento<textarea name="reason" required minlength="3" maxlength="2000"></textarea></label><button>Revalidar e aplicar uma vez</button></form>@endif</article>@endforeach</section>
|
|
<section><h2>Aplicações e histórico</h2>@if($closed)<p>Período QA encerrado; consulta preservada, sem reabertura.</p>@endif<p>Débitos {{ $money($b['totals']['debit_minor']) }} · créditos {{ $money($b['totals']['credit_minor']) }}.</p>@foreach($b['journals'] as $j)<article>Lançamento #{{ $j->id }} · {{ $j->journal_on }} · aplicador #{{ $j->posted_by }} · proposta #{{ $j->proposal_id }} / revisão #{{ $j->review_id }} · {{ $j->reason }}</article>@endforeach @foreach($b['events'] as $e)<details><summary>#{{ $e->id }} · {{ $e->kind }} · autor #{{ $e->actor_id }}</summary><p>{{ $e->reason }}</p><pre>{{ $e->previous }}</pre><pre>{{ $e->subsequent }}</pre></details>@endforeach</section>
|
|
@php $last=max($i['pagination']['last_page'],$b['pagination']['last_page'],...array_column($b['evidence_pagination'],'last_page'),...array_column($data['pagination'],'last_page'));$page=$b['pagination']['page']; @endphp<nav aria-label="Páginas das evidências industriais">Página {{ $page }} de {{ $last }} · listas de25 registos @foreach([-1=>'Anterior',1=>'Seguinte'] as $delta=>$label)@if($page+$delta>=1&&$page+$delta<=$last)<a href="?{{ http_build_query(array_filter(['lot_id'=>$i['lot_id'],'page'=>$page+$delta],fn($v)=>$v!==null)) }}">{{ $label }}</a>@endif @endforeach</nav>
|
|
@include('accounting.receipt-recovery')
|
|
</main><script>
|
|
const csrf=@json(csrf_token()),context=@json(session('company_context.token'));
|
|
for(const form of document.querySelectorAll('[data-action]'))form.onsubmit=async e=>{e.preventDefault();const data=Object.fromEntries(new FormData(form));for(const k of ['source_id','proposal_id','journal_id','correction_id'])if(k in data)data[k]=Number(data[k]);const body=JSON.stringify(data);if(form.dataset.body!==body){form.dataset.body=body;form.dataset.key=crypto.randomUUID();}const button=form.querySelector('button');button.disabled=true;document.querySelector('#error').textContent='';try{const r=await fetch('/api/general-ledger/'+form.dataset.action,{method:'POST',credentials:'same-origin',headers:{Accept:'application/json','Content-Type':'application/json','X-CSRF-TOKEN':csrf,'X-SGF-Context':context,'Idempotency-Key':form.dataset.key},body});const result=await r.json();if(!r.ok)throw Error(result.message||'Conferência recusada.');location.reload();}catch(err){document.querySelector('#error').textContent=err.message+' Chave do pedido: '+form.dataset.key+'. Confira novamente a origem, versões e histórico.';}finally{button.disabled=false;}};
|
|
</script></body></html>
|