Implement a comprehensive financial management suite within the Filament admin panel, including new resources for payments and discount codes, along with a financial dashboard. - feat(ui): add Filament Dashboard with finance overview and transaction widgets - feat(ui): implement PaymentResource for monitoring gateway transactions - feat(ui): complete DiscountCodeResource with full CRUD and filtering - feat(wallet): add automatic wallet creation on balance retrieval - fix(wallet): resolve null handling in isFrozen() and balance viewing - fix(db): correct enum type from 'percent' to 'percentage' in discount_codes migration - fix(api): update pricing calculation endpoint to /api/v1/calculate - test: add 21 new feature and service tests covering wallet, payment, and discount logic - chore: remove obsolete PaymentGatewayService and update project status
112 lines
2.8 KiB
PHP
112 lines
2.8 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
|
|
class Wallet extends Model
|
|
{
|
|
use SoftDeletes;
|
|
|
|
protected $fillable = [
|
|
'user_id',
|
|
'balance',
|
|
'total_deposited',
|
|
'total_withdrawn',
|
|
'is_frozen',
|
|
'freeze_reason',
|
|
'frozen_at',
|
|
'frozen_by',
|
|
];
|
|
|
|
protected $casts = [
|
|
'balance' => 'decimal:2',
|
|
'total_deposited' => 'decimal:2',
|
|
'total_withdrawn' => 'decimal:2',
|
|
'is_frozen' => 'boolean',
|
|
'frozen_at' => 'datetime',
|
|
];
|
|
|
|
public function user(): BelongsTo
|
|
{
|
|
return $this->belongsTo(User::class);
|
|
}
|
|
|
|
public function transactions(): HasMany
|
|
{
|
|
return $this->hasMany(WalletTransaction::class)->orderByDesc('created_at');
|
|
}
|
|
|
|
public function completedTransactions(): HasMany
|
|
{
|
|
return $this->transactions()->where('status', 'completed');
|
|
}
|
|
|
|
public function pendingTransactions(): HasMany
|
|
{
|
|
return $this->transactions()->where('status', 'pending');
|
|
}
|
|
|
|
public function activityLogs(): HasMany
|
|
{
|
|
return $this->hasMany(WalletActivityLog::class)->orderByDesc('created_at');
|
|
}
|
|
|
|
public function frozenByUser(): BelongsTo
|
|
{
|
|
return $this->belongsTo(User::class, 'frozen_by');
|
|
}
|
|
|
|
// Helper methods
|
|
public function isFrozen(): bool
|
|
{
|
|
return (bool) ($this->is_frozen ?? false);
|
|
}
|
|
|
|
public function hasSufficientBalance(float $amount): bool
|
|
{
|
|
return $this->balance >= $amount && !$this->is_frozen;
|
|
}
|
|
|
|
public function freeze(string $reason, ?User $admin = null): bool
|
|
{
|
|
return $this->update([
|
|
'is_frozen' => true,
|
|
'freeze_reason' => $reason,
|
|
'frozen_at' => now(),
|
|
'frozen_by' => $admin?->id,
|
|
]);
|
|
}
|
|
|
|
public function unfreeze(?User $admin = null): bool
|
|
{
|
|
return $this->update([
|
|
'is_frozen' => false,
|
|
'freeze_reason' => null,
|
|
'frozen_at' => null,
|
|
'frozen_by' => null,
|
|
]);
|
|
}
|
|
|
|
public function refreshBalance(): self
|
|
{
|
|
$balance = $this->completedTransactions()->sum('amount');
|
|
$totalDeposited = $this->completedTransactions()
|
|
->where('type', 'deposit')
|
|
->sum('amount');
|
|
$totalWithdrawn = $this->completedTransactions()
|
|
->whereIn('type', ['withdrawal', 'order_payment'])
|
|
->sum('amount');
|
|
|
|
$this->update([
|
|
'balance' => $balance,
|
|
'total_deposited' => $totalDeposited,
|
|
'total_withdrawn' => abs($totalWithdrawn),
|
|
]);
|
|
|
|
return $this->fresh();
|
|
}
|
|
} |