33 lines
3.3 KiB
PHP
33 lines
3.3 KiB
PHP
<?php
|
|
namespace App\Modules\Purchasing;
|
|
|
|
use App\Shared\Context\CompanyContext;
|
|
use App\Shared\Installation\CompositionRuntime;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Tempo\Purchasing\Embedded\Models\PurchaseOrder;
|
|
use Tempo\Purchasing\Embedded\Services\SupplierPayables;
|
|
|
|
/** Financial effects remain in the original authoritative obligation book. */
|
|
final class ComposedFinance
|
|
{
|
|
private const ACTIONS=['view'=>['finance_prepare','finance_review','read_only'],'payment-prepare'=>['finance_prepare'],'allocation-prepare'=>['finance_prepare'],'reversal-prepare'=>['finance_prepare'],'payment-decide'=>['finance_review'],'allocation-decide'=>['finance_review'],'reversal-confirm'=>['finance_review']];
|
|
public function run(string $action,\Closure $work):mixed
|
|
{
|
|
CompositionRuntime::assert();abort_unless(config('sgf_single_installation.finance_enabled')===true,404);abort_unless(isset(self::ACTIONS[$action]),404);
|
|
abort_unless(request()->session()->get('company_context.module_id')==='finance',409,'Seleccione Financeiro.');
|
|
$ctx=app(CompanyContext::class);$scope=$ctx->identifiers()+['unit_id'=>$ctx->unitId()];$host=DB::connection();$user=$ctx->userId();
|
|
try{return $host->transaction(function()use($action,$work,$scope,$host,$user){
|
|
$host->statement("SET LOCAL lock_timeout='5s'");$host->table('companies')->where('tenant_id',$scope['tenant_id'])->where('id',$scope['company_id'])->lockForUpdate()->firstOrFail();
|
|
$profile=$host->table('sgf_presentation_profiles')->where($scope)->where('user_id',$user)->first();abort_unless($profile&&in_array($profile->profile_key,self::ACTIONS[$action],true),403);
|
|
return app(ReceiptRuntime::class)->run('supplier_payables.view',function($actor,$binding,$revision,$origin)use($action,$work,$scope,$host,$user,$profile){
|
|
$r=DB::table('gl_sgf_composition')->where('tenant_id',$actor->tenant_id)->first();abort_unless($r&&$r->host_database===$host->getDatabaseName()&&(int)$r->company_id===$scope['company_id']&&(int)$r->unit_id===$scope['unit_id'],403);
|
|
$orders=PurchaseOrder::visibleTo($actor)->where(fn($q)=>$q->whereIn('id',$binding['order_ids']??[])->orWhereIn('requisition_id',RequisitionAccess::ids($binding)));
|
|
$unknown=DB::table('pa_sources as s')->join('pa_obligations as o','o.source_id','=','s.id')->join('invoices as i','i.id','=','s.local_source_id')->where(['s.tenant_id'=>$actor->tenant_id,'s.company_id'=>0,'s.unit_id'=>0])->whereNotIn('i.purchase_order_id',$orders->select('id'))->exists();
|
|
abort_if($unknown,503,'Há origens financeiras sem unidade conferida; a partição tem de ser resolvida explicitamente.');
|
|
$service=app(SupplierPayables::class);$service->readContext($actor);$engine=$service->engine($actor);
|
|
return $work($engine,$engine->settlements(),$actor,$origin+['sgf_host_user'=>$user,'sgf_host_scope'=>$scope,'profile'=>$profile->profile_key],$orders);
|
|
});
|
|
});}catch(\Illuminate\Database\QueryException $e){if(!in_array($e->errorInfo[0]??null,['55P03','57014'],true))throw $e;return response()->json(['message'=>'Livro ocupado. Recupere a mesma operação, conservando a chave e os dados.'],503)->header('Retry-After','5')->header('Cache-Control','no-store');}
|
|
}
|
|
}
|