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
+21 -2
View File
@@ -28,6 +28,7 @@ class PurchaseWorkflow
return DB::transaction(function () use ($user, $requisition, $data) {
$this->guard->lockCompany($user);
$user = app(CurrentActor::class)->lock($user, [PurchasingRole::Procurement]);
abort_if(app(OrganizationAccess::class)->maintenanceOnly($user), 403);
$requisition = Requisition::query()->lockForUpdate()->findOrFail($requisition->id);
abort_unless($user->hasFunctions([PurchasingRole::Procurement]) && $user->id !== $requisition->requester_id, 403);
if (PurchaseAward::query()->where('requisition_id', $requisition->id)->exists()) {
@@ -64,7 +65,8 @@ class PurchaseWorkflow
public function canDecide(User $user, PurchaseAward $award, Requisition $requisition): bool
{
if ($award->status !== 'pending' || $user->tenant_id !== $award->tenant_id || in_array($user->id, [$requisition->requester_id, $award->created_by])) {
if ($award->status !== 'pending' || $user->tenant_id !== $award->tenant_id || $requisition->tenant_id !== $award->tenant_id || $requisition->id !== $award->requisition_id
|| in_array($user->id, [$requisition->requester_id, $award->created_by]) || app(OrganizationAccess::class)->maintenanceOnly($user) || $this->pendingCancellation($award)) {
return false;
}
$steps = $award->approvals()->get();
@@ -75,6 +77,17 @@ class PurchaseWorkflow
! $steps->contains('approver_id', $user->id) && ! $this->guard->participationBlocked($user, $requisition);
}
/** Eligibility to confer issuance; currentBasis and all final checks still run on issue. */
public function canIssue(User $user, PurchaseAward $award, Requisition $requisition): bool
{
return $user->tenant_id === $award->tenant_id && $requisition->tenant_id === $award->tenant_id && $requisition->id === $award->requisition_id
&& $award->status === 'approved' && $user->hasFunctions([PurchasingRole::Procurement])
&& ! app(OrganizationAccess::class)->maintenanceOnly($user) && ! $this->pendingCancellation($award)
&& ! PurchaseOrder::query()->where('requisition_id', $requisition->id)->exists()
&& Requisition::query()->visibleTo($user)->whereKey($requisition->id)->exists()
&& ! $this->guard->participationBlocked($user, $requisition);
}
public function decide(User $user, PurchaseAward $award, string $decision, ?string $comment): void
{
DB::transaction(function () use ($user, $award, $decision, $comment) {
@@ -103,6 +116,7 @@ class PurchaseWorkflow
return DB::transaction(function () use ($user, $award) {
$this->guard->lockCompany($user);
$user = app(CurrentActor::class)->lock($user, [PurchasingRole::Procurement]);
abort_if(app(OrganizationAccess::class)->maintenanceOnly($user), 403);
abort_unless($user->hasFunctions([PurchasingRole::Procurement]), 403);
$requisition = Requisition::query()->lockForUpdate()->findOrFail($award->requisition_id);
$award = PurchaseAward::query()->lockForUpdate()->findOrFail($award->id);
@@ -313,8 +327,13 @@ class PurchaseWorkflow
private function assertNoPendingCancellation(PurchaseAward $award): void
{
if (AwardCancellation::query()->where('purchase_award_id', $award->id)->where('status', 'pending')->exists()) {
if ($this->pendingCancellation($award)) {
throw ValidationException::withMessages(['cancellation' => 'Existe pedido de cancelamento pendente. Aguarde a decisão antes de aprovar ou emitir.']);
}
}
private function pendingCancellation(PurchaseAward $award): bool
{
return AwardCancellation::query()->where('purchase_award_id', $award->id)->where('status', 'pending')->exists();
}
}