Two issues caused the rate import to fail with 1237 'Out of range value for column rate' errors: 1. The rate column was decimal(12,4) — max ~100 million. Converted IRR values for larger shipments exceed this. Migrate to decimal(20,4) which handles up to ~100 trillion. 2. The fallback AED→IRR rate in config/ifnex.php was 455,000 (way too high — should be ~14,000). Update to a realistic market rate. Also improve the CurrencyResource helperText to remind users to enter rates in Rials (not Tomans) and provide realistic examples for AED, USD, and EUR.
124 lines
5.3 KiB
PHP
124 lines
5.3 KiB
PHP
<?php
|
|
|
|
namespace App\Filament\Resources;
|
|
|
|
use App\Filament\Resources\CurrencyResource\Pages;
|
|
use App\Models\Currency;
|
|
use App\Services\ExchangeRateService;
|
|
use Filament\Forms;
|
|
use Filament\Forms\Form;
|
|
use Filament\Resources\Resource;
|
|
use Filament\Tables;
|
|
use Filament\Tables\Table;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Filament\Notifications\Notification;
|
|
|
|
class CurrencyResource extends Resource
|
|
{
|
|
protected static ?string $model = Currency::class;
|
|
protected static ?string $navigationIcon = 'heroicon-o-currency-yen';
|
|
protected static ?string $navigationLabel = 'ارزها';
|
|
protected static ?string $navigationGroup = 'تنظیمات';
|
|
protected static ?int $navigationSort = 4;
|
|
|
|
public static function form(Form $form): Form
|
|
{
|
|
return $form
|
|
->schema([
|
|
Forms\Components\Section::make('اطلاعات ارز')
|
|
->schema([
|
|
Forms\Components\TextInput::make('code')
|
|
->required()
|
|
->maxLength(10)
|
|
->unique(ignoreRecord: true)
|
|
->label('کد ارز (مثل AED, USD, EUR)'),
|
|
Forms\Components\TextInput::make('name')
|
|
->required()
|
|
->maxLength(100)
|
|
->label('نام ارز'),
|
|
Forms\Components\TextInput::make('symbol')
|
|
->maxLength(10)
|
|
->nullable()
|
|
->label('نماد (مثل $, €, د.إ)'),
|
|
])->columns(3),
|
|
|
|
Forms\Components\Section::make('نرخ تبدیل به ریال')
|
|
->schema([
|
|
Forms\Components\TextInput::make('rate_to_rial')
|
|
->required()
|
|
->numeric()
|
|
->default(0)
|
|
->suffix('ریال')
|
|
->label('نرخ نسبت به ریال')
|
|
->helperText('⚠️ مقدار به ریال (نه تومان) وارد کنید. مثالهای واقعی: AED ≈ 14,000 ریال (1,400 تومان) | USD ≈ 53,000 ریال (5,300 تومان) | EUR ≈ 58,000 ریال (5,800 تومان). با تغییر این فیلد، نرخ جدید در تاریخچه ثبت میشود.'),
|
|
Forms\Components\Toggle::make('is_active')
|
|
->default(true)
|
|
->label('فعال'),
|
|
])->columns(2),
|
|
]);
|
|
}
|
|
|
|
public static function table(Table $table): Table
|
|
{
|
|
return $table
|
|
->columns([
|
|
Tables\Columns\TextColumn::make('code')
|
|
->searchable()
|
|
->sortable()
|
|
->badge()
|
|
->label('کد'),
|
|
Tables\Columns\TextColumn::make('name')
|
|
->searchable()
|
|
->sortable()
|
|
->label('نام'),
|
|
Tables\Columns\TextColumn::make('symbol')
|
|
->label('نماد'),
|
|
Tables\Columns\TextColumn::make('rate_to_rial')
|
|
->sortable()
|
|
->formatStateUsing(fn ($state) => number_format((float) $state, 0))
|
|
->label('نرخ به ریال'),
|
|
Tables\Columns\IconColumn::make('is_active')
|
|
->boolean()
|
|
->label('فعال'),
|
|
])
|
|
->filters([
|
|
Tables\Filters\TernaryFilter::make('is_active')
|
|
->label('وضعیت'),
|
|
])
|
|
->actions([
|
|
Tables\Actions\EditAction::make()
|
|
->mutateFormDataUsing(function (array $data, Currency $record): array {
|
|
// اگه نرخ تغییر کرده، در تاریخچه ثبت کن
|
|
if ((float) $data['rate_to_rial'] !== (float) $record->getOriginal('rate_to_rial')) {
|
|
app(ExchangeRateService::class)->setRate(
|
|
currencyCode: $record->code,
|
|
newRate: (float) $data['rate_to_rial'],
|
|
userId: Auth::id(),
|
|
notes: 'تغییر از پنل مدیریت ارزها'
|
|
);
|
|
|
|
Notification::make()
|
|
->title('نرخ ارز بهروز شد')
|
|
->body("نرخ {$record->code} به " . number_format($data['rate_to_rial']) . " ریال تغییر یافت و در تاریخچه ثبت شد.")
|
|
->success()
|
|
->send();
|
|
}
|
|
return $data;
|
|
}),
|
|
])
|
|
->bulkActions([
|
|
Tables\Actions\BulkActionGroup::make([
|
|
Tables\Actions\DeleteBulkAction::make(),
|
|
]),
|
|
]);
|
|
}
|
|
|
|
public static function getPages(): array
|
|
{
|
|
return [
|
|
'index' => Pages\ListCurrencies::route('/'),
|
|
'create' => Pages\CreateCurrency::route('/create'),
|
|
'edit' => Pages\EditCurrency::route('/{record}/edit'),
|
|
];
|
|
}
|
|
} |