This commit is contained in:
2026-11-02 20:27:11 +02:00
parent b44378b899
commit badaada043
300 changed files with 17458 additions and 1056 deletions
+37 -2
View File
@@ -15,12 +15,47 @@ use Brick\Math\BigDecimal;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
class ExternalPaymentWorkflow
{
private function actor(User $user, int $tenantId): void
{
abort_unless(auth()->id() === $user->id && $user->tenant_id === $tenantId && $user->hasFunctions([PurchasingRole::Finance]), 403);
abort_unless(auth()->id() === $user->id && $user->tenant_id === $tenantId && $user->hasFunctions([PurchasingRole::Finance]) && ! app(OrganizationAccess::class)->maintenanceOnly($user), 403);
}
private function reviewerBaseEligible(User $user, ExternalPayment $payment): bool
{
return $user->tenant_id === $payment->tenant_id && $payment->created_by !== $user->id
&& $user->hasFunctions([PurchasingRole::Finance]) && ! app(OrganizationAccess::class)->maintenanceOnly($user);
}
/** The confirmation still rechecks bank, balance, author and evidence in its transaction. */
public function reviewerEligible(User $user, ExternalPayment $payment): bool
{
if ($payment->status !== 'pending' || ! $this->reviewerBaseEligible($user, $payment)) {
return false;
}
$invoice = Invoice::query()->whereKey($payment->invoice_id)->first();
$order = $invoice === null ? null : PurchaseOrder::query()->whereKey($invoice->purchase_order_id)->first();
if ($invoice === null || $order === null) {
return false;
}
$request = Requisition::query()->visibleTo($user)->whereKey($order->requisition_id)->first();
if ($request === null || app(ConflictGuard::class)->processBlocked($request, $order->supplier_id, $user)) {
return false;
}
try {
app(SupplierPayables::class)->assertHistoricalReview($user, $invoice);
} catch (HttpExceptionInterface $error) {
if (! in_array($error->getStatusCode(), [403, 409], true)) {
throw $error;
}
return false;
}
return true;
}
private function invalid(string $message): never
@@ -100,7 +135,7 @@ class ExternalPaymentWorkflow
public function review(User $user, ExternalPayment $payment, string $decision, string $reason): void
{
$this->actor($user, $payment->tenant_id);
abort_if($payment->created_by === $user->id, 403);
abort_unless($this->reviewerBaseEligible($user, $payment), 403);
if (! in_array($decision, ['confirmed', 'rejected']) || trim($reason) === '') {
$this->invalid('Decisão e fundamento obrigatórios.');
}