Accept technical extraction of shared budget core with QA limits
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
function budgetQaAssert(bool $condition, string $message): void
|
||||
{
|
||||
if (! $condition) throw new RuntimeException($message);
|
||||
}
|
||||
|
||||
function budgetQaFixture(string $mode): array
|
||||
{
|
||||
if ($mode === 'compras') {
|
||||
require_once base_path('tests/Support/ReceiptFixture.php');
|
||||
$f = receiptFixture();
|
||||
$a = \App\Models\User::factory()->create(['tenant_id'=>$f['tenant']->id,'department_id'=>$f['department']->id,'purchasing_role'=>'finance']);
|
||||
$v = \App\Models\User::factory()->create(['tenant_id'=>$f['tenant']->id,'department_id'=>$f['department']->id,'purchasing_role'=>'admin']);
|
||||
return ['actor'=>$a->id,'validator'=>$v->id,'tenant'=>$f['tenant']->id,'centre'=>$f['r']->cost_center_id,'origin'=>$f['r']->id,'invoice'=>$f['order']->id,'scope'=>['tenant_id'=>$f['tenant']->id]];
|
||||
}
|
||||
$now = now();
|
||||
$tenant = DB::table('tenants')->insertGetId(['name'=>'Synthetic tenant','created_at'=>$now,'updated_at'=>$now]);
|
||||
// Deliberately different tenant/company/unit identifiers, no numeric equivalence.
|
||||
DB::table('companies')->insert(['tenant_id'=>$tenant,'name'=>'Unused synthetic company','created_at'=>$now,'updated_at'=>$now]);
|
||||
$company = DB::table('companies')->insertGetId(['tenant_id'=>$tenant,'name'=>'Synthetic purchaser','created_at'=>$now,'updated_at'=>$now]);
|
||||
DB::table('units')->insert(['tenant_id'=>$tenant,'company_id'=>$company,'name'=>'Reserved','created_at'=>$now,'updated_at'=>$now]);
|
||||
$unit = DB::table('units')->insertGetId(['tenant_id'=>$tenant,'company_id'=>$company,'name'=>'Purchasing QA','created_at'=>$now,'updated_at'=>$now]);
|
||||
$scope = ['tenant_id'=>$tenant,'company_id'=>$company,'unit_id'=>$unit];
|
||||
$a = \App\Models\User::create(['name'=>'Synthetic preparer','email'=>'prepare-'.bin2hex(random_bytes(6)).'@example.test','password'=>bin2hex(random_bytes(20))]);
|
||||
$v = \App\Models\User::create(['name'=>'Synthetic validator','email'=>'validate-'.bin2hex(random_bytes(6)).'@example.test','password'=>bin2hex(random_bytes(20))]);
|
||||
foreach ([$a,$v] as $u) {
|
||||
DB::table('company_memberships')->insert(['user_id'=>$u->id,'tenant_id'=>$tenant,'company_id'=>$company]);
|
||||
foreach (['company.view'=>null,'unit.view'=>$unit] as $right=>$unitId) DB::table('permission_grants')->insert(['user_id'=>$u->id,'tenant_id'=>$tenant,'company_id'=>$company,'unit_id'=>$unitId,'permission'=>$right,'created_at'=>$now,'updated_at'=>$now]);
|
||||
}
|
||||
foreach ([$a->id=>['create','record','consume','view','reinforcement.propose'],$v->id=>['approve','view','reinforcement.review']] as $id=>$rights) foreach ($rights as $right) DB::table('permission_grants')->insert($scope+['user_id'=>$id,'permission'=>'purchasing_budget.'.$right,'created_at'=>$now,'updated_at'=>$now]);
|
||||
$centre = DB::table('cb_centres')->insertGetId($scope+['code'=>'CENTRE-TEST']);
|
||||
$origin = DB::table('cb_origins')->insertGetId($scope+['cost_center_id'=>$centre,'required_kind'=>'operating','reference'=>'REQ-'.bin2hex(random_bytes(6))]);
|
||||
return ['actor'=>$a->id,'validator'=>$v->id,'tenant'=>$tenant,'company'=>$company,'unit'=>$unit,'centre'=>$centre,'origin'=>$origin,'invoice'=>$origin,'scope'=>$scope];
|
||||
}
|
||||
|
||||
function budgetQaSelect(string $mode, array $f, string $role='actor'): object
|
||||
{
|
||||
$user = \App\Models\User::findOrFail($f[$role]);
|
||||
auth()->guard()->setUser($user);
|
||||
if ($mode === 'sgf') app(\App\Shared\Context\CompanyContext::class)->selectFor($user->id,$f['tenant'],$f['company'],$f['unit']);
|
||||
return $user;
|
||||
}
|
||||
|
||||
function budgetQaEngine(string $mode, array $f, string $role='actor'): \Tempo\Finance\Budget\BudgetControl
|
||||
{
|
||||
$user = budgetQaSelect($mode,$f,$role);
|
||||
return $mode === 'compras' ? app(\App\Services\CommonBudget::class)->for($user) : app(\App\Modules\Purchasing\BudgetAdapter::class)->for($user);
|
||||
}
|
||||
|
||||
function budgetQaRecord(string $mode, array $f, string $kind, int $amount=0): mixed
|
||||
{
|
||||
$user = budgetQaSelect($mode,$f);
|
||||
return DB::transaction(function () use ($mode,$f,$kind,$amount,$user) {
|
||||
if ($mode === 'compras') {
|
||||
$request = \App\Models\Requisition::findOrFail($f['origin']);
|
||||
return app(\App\Services\BudgetWorkflow::class)->record($user,$request,$kind,$amount,$amount);
|
||||
}
|
||||
return app(\App\Modules\Purchasing\BudgetAdapter::class)->record($user,$f['origin'],$kind,$amount,$amount);
|
||||
});
|
||||
}
|
||||
|
||||
function budgetQaCreate(string $mode, array $f, int $amount=100000, bool $tax=true): int
|
||||
{
|
||||
$data = ['cost_center_id'=>$f['centre'],'year'=>(int)now()->year,'kind'=>'operating','amount_minor'=>$amount,'includes_tax'=>$tax,'reason'=>'Synthetic allocation'];
|
||||
$user = budgetQaSelect($mode,$f);
|
||||
$id = $mode==='compras' ? budgetQaEngine($mode,$f)->create($data) : app(\App\Modules\Purchasing\BudgetAdapter::class)->create($user,$data);
|
||||
budgetQaEngine($mode,$f,'validator')->approve($id);
|
||||
return $id;
|
||||
}
|
||||
|
||||
function budgetQaReject(callable $work, string $message): void
|
||||
{
|
||||
try { $work(); } catch (\Tempo\Finance\Budget\BudgetFailure|\Illuminate\Validation\ValidationException|\Symfony\Component\HttpKernel\Exception\HttpException $e) { return; }
|
||||
throw new RuntimeException('Expected rejection: '.$message);
|
||||
}
|
||||
Reference in New Issue
Block a user