ifnex/04_Laravel/app/Models/ExchangeRateHistory.php
Kazem Alghasi ed5bae9997 feat(exchange): implement exchange rate history tracking
Introduce a mechanism to track and audit changes in exchange rates.
This includes:
- Creating `ExchangeRateHistory` model and migration to store rate changes.
- Implementing `ExchangeRateService` to encapsulate rate logic.
- Updating `UpdateExchangeRates` command to record history when rates change.
- Adding `ExchangeRateHistoryResource` to the Filament admin panel for monitoring.
2026-08-10 03:04:18 +03:30

73 lines
1.9 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class ExchangeRateHistory extends Model
{
protected $table = 'exchange_rate_history';
protected $fillable = [
'currency_from',
'currency_to',
'old_rate',
'new_rate',
'change_percent',
'change_source',
'changed_by',
'api_source',
'notes',
];
protected $casts = [
'old_rate' => 'decimal:2',
'new_rate' => 'decimal:2',
'change_percent' => 'decimal:4',
];
public function changedBy(): BelongsTo
{
return $this->belongsTo(User::class, 'changed_by');
}
// Helper برای محاسبه درصد تغییر
public static function calculateChangePercent($old, $new): ?float
{
if (!$old || $old == 0) return null;
return round((($new - $old) / $old) * 100, 4);
}
// Helper برای ثبت تغییر
public static function recordChange(
string $from,
string $to,
float $oldRate,
float $newRate,
string $source = 'manual',
?int $userId = null,
?string $apiSource = null,
?string $notes = null
): self {
return self::create([
'currency_from' => $from,
'currency_to' => $to,
'old_rate' => $oldRate,
'new_rate' => $newRate,
'change_percent' => self::calculateChangePercent($oldRate, $newRate),
'change_source' => $source,
'changed_by' => $userId,
'api_source' => $apiSource,
'notes' => $notes,
]);
}
// Scope برای آخرین تغییر
public function scopeLatest($query, string $from = 'AED', string $to = 'IRR')
{
return $query->where('currency_from', $from)
->where('currency_to', $to)
->orderBy('created_at', 'desc');
}
}