status === static::STATUS_REJECTED; } /** * Check if document/payment is pending (initial state) */ public function isPending(): bool { return $this->status === static::STATUS_PENDING; } /** * Check if self-approval is being attempted * Prevents users from approving their own submissions * * @param User|null $user The user attempting to approve * @param string $submitterField The field containing the submitter's user ID */ protected function isSelfApproval(?User $user, string $submitterField = 'submitted_by_user_id'): bool { if (! $user) { return false; } $submitterId = $this->{$submitterField}; return $submitterId && $submitterId === $user->id; } /** * Get the human-readable status label * Override in model for custom labels */ public function getStatusLabelAttribute(): string { return ucfirst(str_replace('_', ' ', $this->status)); } /** * Check if approval can proceed based on current status * * @param string $requiredStatus The status required before this approval * @param User|null $user The user attempting to approve * @param bool $checkSelfApproval Whether to check for self-approval */ protected function canProceedWithApproval( string $requiredStatus, ?User $user = null, bool $checkSelfApproval = true ): bool { if ($this->status !== $requiredStatus) { return false; } if ($checkSelfApproval && $this->isSelfApproval($user)) { return false; } return true; } /** * Get the rejection details */ public function getRejectionDetails(): ?array { if (! $this->isRejected()) { return null; } return [ 'reason' => $this->rejection_reason ?? null, 'rejected_by' => $this->rejectedBy ?? null, 'rejected_at' => $this->rejected_at ?? null, ]; } /** * Check if model can be rejected * Default: can reject if not already rejected */ public function canBeRejected(): bool { return ! $this->isRejected(); } /** * Get the next approver role required * Override in model to implement specific logic */ public function getNextApproverRole(): ?string { return null; } /** * Get approval history * Returns array of approval stages that have been completed */ public function getApprovalHistory(): array { $history = []; // This should be overridden in each model to provide specific fields // Example structure: // [ // ['stage' => 'cashier', 'user' => User, 'at' => Carbon], // ['stage' => 'accountant', 'user' => User, 'at' => Carbon], // ] return $history; } }