Files
hoshpoint-backend/app/Filament/Resources/Wallets/Tables/WalletsTable.php
soheil khaledabadi d2873ebcc1 fix(wallets): capture $type in the deposit/withdraw action closure
The action closure referenced $type without importing it via use(), so
every credit/debit attempt in the admin panel threw "Undefined variable
$type" instead of adjusting the wallet.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-08 23:59:07 +03:30

113 lines
4.4 KiB
PHP

<?php
namespace App\Filament\Resources\Wallets\Tables;
use App\Models\Wallet;
use App\Services\WalletService;
use Filament\Actions\Action;
use Filament\Actions\EditAction;
use Filament\Actions\ViewAction;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Notifications\Notification;
use Filament\Support\Icons\Heroicon;
use Filament\Tables\Columns\IconColumn;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Filters\TernaryFilter;
use Filament\Tables\Table;
use Throwable;
class WalletsTable
{
public static function configure(Table $table): Table
{
return $table
->columns([
TextColumn::make('user.name')
->label('کاربر')
->searchable()
->sortable(),
TextColumn::make('user.email')
->label('ایمیل')
->searchable()
->toggleable(),
TextColumn::make('user.mobile')
->label('موبایل')
->searchable()
->toggleable(),
TextColumn::make('balance')
->label('موجودی (تومان)')
->numeric()
->sortable()
->formatStateUsing(fn (int $state): string => number_format($state).' تومان'),
IconColumn::make('is_active')
->label('فعال')
->boolean(),
TextColumn::make('updated_at')
->label('آخرین بروزرسانی')
->jalaliDateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
])
->defaultSort('balance', 'desc')
->filters([
TernaryFilter::make('is_active')
->label('وضعیت')
->placeholder('همه')
->trueLabel('فعال')
->falseLabel('غیرفعال'),
])
->recordActions([
ViewAction::make(),
EditAction::make(),
self::adjustAction('credit', 'واریز', Heroicon::OutlinedPlusCircle, 'success'),
self::adjustAction('debit', 'برداشت', Heroicon::OutlinedMinusCircle, 'danger'),
]);
}
private static function adjustAction(string $type, string $label, Heroicon $icon, string $color): Action
{
return Action::make($type)
->label($label)
->icon($icon)
->color($color)
->schema([
TextInput::make('amount')
->label('مبلغ (تومان)')
->numeric()
->required()
->minValue(1)
->integer(),
Textarea::make('description')
->label('توضیحات')
->maxLength(500)
->rows(2),
])
->action(function (Wallet $record, array $data, WalletService $walletService) use ($type): void {
$amount = (int) $data['amount'];
$description = filled($data['description'] ?? null) ? $data['description'] : null;
try {
$transaction = $type === 'credit'
? $walletService->credit($record, $amount, $description, auth()->user())
: $walletService->debit($record, $amount, $description, auth()->user());
Notification::make()
->title($type === 'credit' ? 'واریز انجام شد' : 'برداشت انجام شد')
->body('موجودی جدید: '.number_format($transaction->balance_after).' تومان')
->success()
->send();
} catch (Throwable $exception) {
report($exception);
Notification::make()
->title($type === 'credit' ? 'واریز ناموفق بود' : 'برداشت ناموفق بود')
->body($exception->getMessage() ?: 'خطای نامشخص هنگام ثبت تراکنش.')
->danger()
->persistent()
->send();
}
});
}
}