This commit is contained in:
2026-11-03 11:51:44 +02:00
parent badaada043
commit e753f7a0a4
309 changed files with 14537 additions and 529 deletions
+41
View File
@@ -90,6 +90,47 @@ test('missing configuration records a pending need and never invents a requester
expect($need->state)->toBe('pending')->and($need->data['purchases'])->toBe([])->and($need->data['message'])->toContain('Parametrize')->and(Requisition::query()->count())->toBe($before);
});
test('supply task auto rule approval connects the reviewer to one requester draft while preserving human approvals', function () {
$planning = app(SupplyPlanning::class);
$this->actingAs($this->f['receiver']);
$planning->save($this->f['receiver'], 'policy', supplyInput([], 'suspend', $this->f['policy']));
$this->actingAs($this->f['issuer']);
$draft = $planning->save($this->f['issuer'], 'policy', supplyInput([...supplyPolicy($this->f), 'purpose' => 'internal', 'agreement_key' => $this->f['agreement']->record_key,
'safety_milli' => 120000, 'minimum_stock_milli' => 120000, 'target_milli' => 140000, 'maximum_milli' => 160000, 'daily_milli' => 0, 'minimum_milli' => 0, 'pack_milli' => 1000]));
$this->actingAs($this->f['receiver']);
$policy = $planning->save($this->f['receiver'], 'policy', supplyInput([], 'approve', $draft));
$this->actingAs($this->f['issuer']);
$input = $this->input;
$input['data']['policy_key'] = $policy->record_key;
$rule = app(AutomaticPurchases::class)->save($this->f['issuer'], $input);
supplyGrant($this->f['issuer'], ['supply_review']);
$this->get('/stock/reposicao?rule_id='.$rule->id)->assertInertia(fn (Assert $page) => $page->where('rules.data.0.canApprove', false));
$this->get('/requisicoes/tarefas?module=supply')->assertInertia(fn (Assert $page) => $page->where('tasks.total', 0));
$this->actingAs($this->f['receiver'])->get('/requisicoes/tarefas?module=supply')->assertInertia(fn (Assert $page) => $page->where('tasks.total', 1)
->where('tasks.data.0.href', '/stock/reposicao?rule_id='.$rule->id.'#supply-rule-'.$rule->id));
$this->get('/stock/reposicao?rule_id='.$rule->id)->assertInertia(fn (Assert $page) => $page->where('rules.total', 1)->where('rules.data.0.canApprove', true));
$count = Requisition::query()->count();
$approval = ['operation_key' => (string) Str::uuid(), 'record_key' => $rule->record_key, 'version' => $rule->version, 'action' => 'approve', 'data' => [], 'reason' => 'Conferência independente apenas no ensaio descartável.'];
$this->post('/stock/reposicao', $approval)->assertSessionHasNoErrors();
$this->post('/stock/reposicao', $approval)->assertSessionHasNoErrors();
$requisition = Requisition::query()->where('status', 'draft')->sole();
expect(Requisition::query()->count())->toBe($count + 1)->and($requisition->requester_id)->toBe($this->f['issuer']->id)
->and($requisition->items()->sole()->quantity)->toBe('20.000')->and($requisition->steps()->count())->toBe(0)->and(DB::table('budget_entries')->count())->toBe(0);
$this->get('/requisicoes/tarefas?module=supply')->assertInertia(fn (Assert $page) => $page->where('tasks.total', 0));
$this->get('/stock/reposicao?rule_id='.$rule->id)->assertInertia(fn (Assert $page) => $page->where('focusChanged', true)->where('rules.data.0.state', 'approved')->where('rules.data.0.canApprove', false));
$this->actingAs($this->f['issuer'])->get('/requisicoes/tarefas?module=purchases')->assertInertia(fn (Assert $page) => $page->where('tasks.total', 1)->where('tasks.data.0.task', 'prepare')->where('tasks.data.0.href', '/requisicoes/'.$requisition->id));
expect($requisition->fresh()->status)->toBe('draft');
});
test('supply task auto rule preserves the existing ability of an authorised preparer to suspend an active rule', function () {
$approved = activateAutomaticRule($this);
supplyGrant($this->f['issuer'], ['supply_review']);
$this->actingAs($this->f['issuer'])->get('/stock/reposicao?rule_id='.$approved->id)->assertInertia(fn (Assert $page) => $page->where('rules.data.0.canApprove', false)->where('rules.data.0.canSuspend', true));
expect(app(AutomaticPurchases::class)->canReview($this->f['issuer'], $approved, 'suspend'))->toBeTrue();
$this->post('/stock/reposicao', ['operation_key' => (string) Str::uuid(), 'record_key' => $approved->record_key, 'version' => $approved->version, 'action' => 'suspend', 'data' => [], 'reason' => 'Suspender a regra pelo percurso já existente.'])->assertSessionHasNoErrors();
expect(app(SupplyPlanning::class)->latest('auto_rule')->sole()->state)->toBe('suspended');
});
test('durable signals survive the missing immediate callback and scheduled recovery never impersonates or duplicates drafts', function () {
$id = pilotWork($this);
$before = Requisition::query()->count();