'decimal:2', 'balance_before' => 'decimal:2', 'balance_after' => 'decimal:2', 'type' => TransactionType::class, 'status' => TransactionStatus::class, 'gateway' => PaymentGateway::class, 'approved_at' => 'datetime', 'metadata' => 'array', ]; public function wallet(): BelongsTo { return $this->belongsTo(Wallet::class); } public function creator(): BelongsTo { return $this->belongsTo(User::class, 'created_by'); } public function approver(): BelongsTo { return $this->belongsTo(User::class, 'approved_by'); } public function transactionable(): MorphTo { return $this->morphTo(); } // Scopes public function scopeCompleted($query) { return $query->where('status', TransactionStatus::COMPLETED); } public function scopePending($query) { return $query->where('status', TransactionStatus::PENDING); } public function scopeDeposits($query) { return $query->where('type', TransactionType::DEPOSIT); } public function scopeWithdrawals($query) { return $query->where('type', TransactionType::WITHDRAWAL); } // Helper methods public function isCompleted(): bool { return $this->status === TransactionStatus::COMPLETED; } public function isPending(): bool { return $this->status === TransactionStatus::PENDING; } public function approve(?User $admin = null): bool { return $this->update([ 'status' => TransactionStatus::COMPLETED, 'approved_by' => $admin?->id, 'approved_at' => now(), ]); } public function fail(string $reason = null): bool { $metadata = $this->metadata ?? []; $metadata['fail_reason'] = $reason; return $this->update([ 'status' => TransactionStatus::FAILED, 'metadata' => $metadata, ]); } public function getFormattedAmountAttribute(): string { $prefix = $this->amount >= 0 ? '+' : ''; return $prefix . number_format($this->amount, 0) . ' ریال'; } public function getGatewayLabelAttribute(): string { return $this->gateway?->label() ?? 'نامشخص'; } }