23 lines
3.5 KiB
PHP
23 lines
3.5 KiB
PHP
<?php
|
|
namespace App\Modules\Accounting;
|
|
use App\Models\User;use App\Modules\Finance\CashWorkspace;use Illuminate\Support\Facades\DB;use Tempo\Finance\Payables\Payables;
|
|
final class CashLedgerSource
|
|
{
|
|
public function source(User $u,string $kind,int $id):array
|
|
{
|
|
$cash=app(CashWorkspace::class);$s=$cash->scope($u->id,'view',true);$b=$cash->binding();$row=DB::table('cash_events')->where($s)->where(['id'=>$id,'session_key'=>$b['session_key'],'action'=>'review','state'=>'approved','kind'=>$kind==='cash.receipt_classified'?'receipt':'expense'])->first()??throw new \DomainException('Origem de Caixa fora do âmbito.');
|
|
$p=DB::table('cash_events')->where($s)->where(['id'=>$row->proposal_id,'action'=>'prepare','kind'=>$row->kind])->first();$data=json_decode($row->data,true);$deps=json_decode($row->dependencies,true);$receipt=$cash->receipt($s,$b);$hash=hash('sha256',Payables::canonical($receipt));
|
|
if(!$p||$p->actor_id===$row->actor_id||Payables::canonical(json_decode($p->data,true))!==Payables::canonical($data)||($deps['source']??null)!==$hash||!($deps['open']??false)||$data['amount_minor']!==($row->kind==='receipt'?100000:5000))throw new \DomainException('Caixa sem proposta, origem e revisão distintas.');
|
|
if($row->kind==='receipt'&&!SourceBook::table('gl_journals')->where($s)->where('snapshot->source->effect_type','receivable.allocated')->where('snapshot->source->source_id',$receipt['allocation']['id'])->exists())throw new \DomainException('Contabilize primeiro a afectação original; a Caixa só reclassifica a liquidez já reconhecida.');
|
|
return ['effect_type'=>$kind,'source_id'=>$id,'obligation_id'=>$id,'origin_key'=>hash('sha256',Payables::canonical([$s,$b['session_key']])),'amount_minor'=>$data['amount_minor'],'principal_minor'=>$data['amount_minor'],'tax_minor'=>0,'currency'=>'MZN','compatible'=>true,'history_imported'=>false,'cash_effect_on'=>$data['date'],'permitted_period_key'=>$b['period_key'],'recognition_revision'=>hash('sha256',Payables::canonical(['event'=>(array)$row,'proposal'=>(array)$p,'source'=>$receipt])),'cash_event'=>(array)$row];
|
|
}
|
|
public function period(User $u,array $period):array
|
|
{
|
|
if(config('cash_qa.enabled')!==true)return ['facts'=>0,'pending'=>0,'hash'=>hash('sha256','cash-disabled')];$cash=app(CashWorkspace::class);$s=$cash->scope($u->id,'view',true);$b=$cash->binding();$facts=0;$pending=0;$h=hash_init('sha256');$q=DB::table('cash_events')->where($s);
|
|
foreach((clone$q)->orderBy('id')->cursor() as $row){$facts++;hash_update($h,Payables::canonical((array)$row));if($row->session_key!==$b['session_key']){$pending++;continue;}if($row->action==='prepare'&&!(clone$q)->where('proposal_id',$row->id)->where('action','review')->exists())$pending++;
|
|
if($row->action==='review'&&$row->state==='approved'&&in_array($row->kind,['receipt','expense'],true)){try{$type=$row->kind==='receipt'?'cash.receipt_classified':'cash.expense_confirmed';$source=$this->source($u,$type,$row->id);if(!SourceBook::table('gl_journals')->where($s)->where('snapshot->source->effect_type',$type)->where('snapshot->source->source_id',$row->id)->where('snapshot->source->recognition_revision',$source['recognition_revision'])->exists())$pending++;}catch(\DomainException|\Symfony\Component\HttpKernel\Exception\HttpExceptionInterface){$pending++;}}
|
|
}
|
|
if($facts>0&&!(clone$q)->where(['session_key'=>$b['session_key'],'state'=>'closed'])->exists())$pending++;return ['facts'=>$facts,'pending'=>$pending,'hash'=>hash_final($h)];
|
|
}
|
|
}
|