namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Wallet extends Model { use HasFactory; protected $fillable = [ 'user_id', 'balance', 'pending_balance', 'total_deposited', 'total_withdrawn', 'total_spent', 'currency', 'status', 'last_transaction_at', ]; protected $casts = [ 'balance' => 'decimal:2', 'pending_balance' => 'decimal:2', 'total_deposited' => 'decimal:2', 'total_withdrawn' => 'decimal:2', 'total_spent' => 'decimal:2', 'last_transaction_at' => 'datetime', ]; protected $appends = [ 'available_balance', 'is_active', ]; // Relationships public function user() { return $this->belongsTo(User::class); } public function transactions() { return $this->hasMany(Transaction::class); } public function deposits() { return $this->hasMany(Deposit::class); } public function withdrawals() { return $this->hasMany(Withdrawal::class); } // Accessors public function getAvailableBalanceAttribute() { return $this->balance - $this->pending_balance; } public function getIsActiveAttribute() { return $this->status === 'active'; } public function getFormattedBalanceAttribute() { return number_format($this->balance, 2) . ' ' . $this->currency; } public function getFormattedPendingAttribute() { return number_format($this->pending_balance, 2) . ' ' . $this->currency; } // Methods public function credit($amount, $description, $type = 'deposit', $reference = null) { $before = $this->balance; $this->balance += $amount; $this->total_deposited += $amount; $this->last_transaction_at = now(); $this->save(); return $this->createTransaction([ 'type' => $type, 'amount' => $amount, 'balance_before' => $before, 'balance_after' => $this->balance, 'description' => $description, 'reference_id' => $reference?->id, 'reference_type' => $reference ? get_class($reference) : null, ]); } public function debit($amount, $description, $type = 'order', $reference = null) { if ($this->available_balance < $amount) { throw new \Exception('Insufficient balance'); } $before = $this->balance; $this->balance -= $amount; $this->total_spent += $amount; $this->last_transaction_at = now(); $this->save(); return $this->createTransaction([ 'type' => $type, 'amount' => -$amount, 'balance_before' => $before, 'balance_after' => $this->balance, 'description' => $description, 'reference_id' => $reference?->id, 'reference_type' => $reference ? get_class($reference) : null, ]); } protected function createTransaction($data) { return Transaction::create([ 'user_id' => $this->user_id, 'wallet_id' => $this->id, 'transaction_id' => $this->generateTransactionId(), 'type' => $data['type'], 'amount' => abs($data['amount']), 'net_amount' => abs($data['amount']), 'balance_before' => $data['balance_before'], 'balance_after' => $data['balance_after'], 'description' => $data['description'], 'status' => 'completed', 'reference_id' => $data['reference_id'], 'reference_type' => $data['reference_type'], ]); } protected function generateTransactionId() { return 'TXN-' . strtoupper(uniqid() . bin2hex(random_bytes(4))); } }