):array $basis */ public function executionSourceCurrent(SupplyRecord $record, Closure $basis): bool { if ($record->state !== 'approved' || ! isset($record->snapshot['source'])) { return false; } try { return $basis($record->data)['source'] === $record->snapshot['source']; } catch (ValidationException|ModelNotFoundException) { return false; } } public function independentReviewer(User $actor, SupplyRecord $record): bool { return ! in_array($actor->id, $record->snapshot['contributors'], true); } public function independentExecutor(User $actor, SupplyRecord $record): bool { return isset($record->snapshot['reviewed_by']) && $actor->id !== $record->snapshot['reviewed_by']; } /** @param Closure(string):bool $allows */ public function canAct(User $actor, SupplyRecord $record, string $kind, string $action, Closure $allows): bool { if (! in_array($kind, ['stock_event', 'stock_reversal'], true) || $record->kind !== $kind || $record->tenant_id !== $actor->tenant_id || ! in_array($action, ['approve', 'return', 'execute'], true) || ! $allows($action === 'execute' ? 'execute' : 'review')) { return false; } $latest = app(SupplyPlanning::class)->latest($kind)->where('record_key', $record->record_key)->first(); if ($latest?->id !== $record->id) { return false; } return $action === 'execute' ? $record->state === 'approved' && $this->independentExecutor($actor, $record) : $this->independentReviewer($actor, $record) && in_array($record->state, $action === 'return' ? ['draft', 'returned', 'approved'] : ['draft', 'returned'], true); } }