feat(admin): enhance shipment and wallet transaction resources

- Refactor ShipmentResource to improve form schema formatting and structure
- Update WalletTransactionResource with improved navigation icons and Persian labels
- Implement dynamic transaction type options using enum cases
- Add dedicated Create and Edit pages for WalletTransactionResource to support full CRUD operations
This commit is contained in:
Kazem Alghasi 2026-08-10 00:25:15 +03:30
parent 810004aab1
commit bc52e94dc3
4 changed files with 425 additions and 155 deletions

View File

@ -3,14 +3,14 @@
namespace App\Filament\Resources; namespace App\Filament\Resources;
use App\Filament\Resources\ShipmentResource\Pages; use App\Filament\Resources\ShipmentResource\Pages;
use App\Filament\Resources\ShipmentResource\RelationManagers;
use App\Models\Shipment; use App\Models\Shipment;
use Filament\Forms; use Filament\Forms;
use Filament\Forms\Form; use Filament\Forms\Form;
use Filament\Resources\Resource; use Filament\Resources\Resource;
use Filament\Tables; use Filament\Tables;
use Filament\Tables\Table; use Filament\Tables\Table;
use App\Exports\ShipmentsExport; use Filament\Tables\Actions\Action;
use Filament\Tables\Actions\ExportAction;
class ShipmentResource extends Resource class ShipmentResource extends Resource
{ {
@ -33,7 +33,10 @@ class ShipmentResource extends Resource
->unique(ignoreRecord: true) ->unique(ignoreRecord: true)
->label('AWB No.'), ->label('AWB No.'),
Forms\Components\Select::make('direction') Forms\Components\Select::make('direction')
->options(['export' => 'Export', 'import' => 'Import']) ->options([
'export' => 'Export',
'import' => 'Import'
])
->required(), ->required(),
Forms\Components\Select::make('type') Forms\Components\Select::make('type')
->options([ ->options([
@ -54,8 +57,12 @@ class ShipmentResource extends Resource
]) ])
->default('processed') ->default('processed')
->required(), ->required(),
Forms\Components\TextInput::make('reason_for_export')->nullable()->label('Reason for Export'), Forms\Components\TextInput::make('reason_for_export')
Forms\Components\TextInput::make('forwarder')->nullable()->label('Forwarder'), ->nullable()
->label('Reason for Export'),
Forms\Components\TextInput::make('forwarder')
->nullable()
->label('Forwarder'),
Forms\Components\Select::make('from_country_id') Forms\Components\Select::make('from_country_id')
->relationship('fromCountry', 'name') ->relationship('fromCountry', 'name')
->searchable() ->searchable()
@ -70,49 +77,143 @@ class ShipmentResource extends Resource
Forms\Components\Section::make('Weight & Dimensions') Forms\Components\Section::make('Weight & Dimensions')
->schema([ ->schema([
Forms\Components\TextInput::make('weight')->numeric()->nullable()->suffix('kg')->label('Weight'), Forms\Components\TextInput::make('weight')
Forms\Components\TextInput::make('volumetric_weight')->numeric()->nullable()->suffix('kg')->label('Volumetric Weight'), ->numeric()
Forms\Components\TextInput::make('chargeable_weight')->numeric()->nullable()->suffix('kg')->label('Chargeable Weight'), ->nullable()
Forms\Components\TextInput::make('dimensions')->nullable()->label('Dimensions (WxLxH)'), ->suffix('kg')
->label('Weight'),
Forms\Components\TextInput::make('volumetric_weight')
->numeric()
->nullable()
->suffix('kg')
->label('Volumetric Weight'),
Forms\Components\TextInput::make('chargeable_weight')
->numeric()
->nullable()
->suffix('kg')
->label('Chargeable Weight'),
Forms\Components\TextInput::make('dimensions')
->nullable()
->label('Dimensions (WxLxH)'),
])->columns(4), ])->columns(4),
Forms\Components\Section::make('Financial Info') Forms\Components\Section::make('Financial Info')
->schema([ ->schema([
Forms\Components\TextInput::make('shipping_price')->numeric()->nullable()->prefix('درهم')->label('Shipping Price'), Forms\Components\TextInput::make('shipping_price')
Forms\Components\TextInput::make('extra_service')->numeric()->default(0)->prefix('درهم')->label('Extra Service'), ->numeric()
Forms\Components\TextInput::make('packing_cost')->numeric()->default(0)->prefix('ریال')->label('Packing Cost'), ->nullable()
Forms\Components\TextInput::make('domestic_pickup')->numeric()->default(0)->prefix('ریال')->label('Domestic Pickup'), ->prefix('درهم')
Forms\Components\TextInput::make('domestic_delivery')->numeric()->default(0)->prefix('ریال')->label('Domestic Delivery'), ->label('Shipping Price'),
Forms\Components\TextInput::make('warehousing_cost')->numeric()->default(0)->prefix('ریال')->label('Warehousing Cost'), Forms\Components\TextInput::make('extra_service')
Forms\Components\TextInput::make('vat_amount')->numeric()->default(0)->prefix('ریال')->label('VAT Amount'), ->numeric()
Forms\Components\TextInput::make('discount')->numeric()->default(0)->prefix('ریال')->label('Discount'), ->default(0)
Forms\Components\TextInput::make('total_fee')->numeric()->nullable()->prefix('ریال')->label('Total Fee'), ->prefix('درهم')
Forms\Components\TextInput::make('net_dirham')->numeric()->nullable()->prefix('درهم')->label('Net Dirham'), ->label('Extra Service'),
Forms\Components\TextInput::make('net_rial')->numeric()->nullable()->prefix('ریال')->label('Net Rial'), Forms\Components\TextInput::make('packing_cost')
->numeric()
->default(0)
->prefix('ریال')
->label('Packing Cost'),
Forms\Components\TextInput::make('domestic_pickup')
->numeric()
->default(0)
->prefix('ریال')
->label('Domestic Pickup'),
Forms\Components\TextInput::make('domestic_delivery')
->numeric()
->default(0)
->prefix('ریال')
->label('Domestic Delivery'),
Forms\Components\TextInput::make('warehousing_cost')
->numeric()
->default(0)
->prefix('ریال')
->label('Warehousing Cost'),
Forms\Components\TextInput::make('vat_amount')
->numeric()
->default(0)
->prefix('ریال')
->label('VAT Amount'),
Forms\Components\TextInput::make('discount')
->numeric()
->default(0)
->prefix('ریال')
->label('Discount'),
Forms\Components\TextInput::make('total_fee')
->numeric()
->nullable()
->prefix('ریال')
->label('Total Fee'),
Forms\Components\TextInput::make('net_dirham')
->numeric()
->nullable()
->prefix('درهم')
->label('Net Dirham'),
Forms\Components\TextInput::make('net_rial')
->numeric()
->nullable()
->prefix('ریال')
->label('Net Rial'),
])->columns(4), ])->columns(4),
Forms\Components\Section::make('Sender Info') Forms\Components\Section::make('Sender Info')
->schema([ ->schema([
Forms\Components\TextInput::make('sender_name')->nullable()->label('Name'), Forms\Components\TextInput::make('sender_name')
Forms\Components\TextInput::make('sender_company')->nullable()->label('Company'), ->nullable()
Forms\Components\TextInput::make('sender_phone')->tel()->nullable()->label('Phone'), ->label('Name'),
Forms\Components\TextInput::make('sender_email')->email()->nullable()->label('Email'), Forms\Components\TextInput::make('sender_company')
Forms\Components\TextInput::make('sender_address')->nullable()->label('Address'), ->nullable()
Forms\Components\TextInput::make('sender_city')->nullable()->label('City'), ->label('Company'),
Forms\Components\TextInput::make('sender_zip')->nullable()->label('ZIP'), Forms\Components\TextInput::make('sender_phone')
Forms\Components\TextInput::make('sender_id_number')->nullable()->label('ID Number'), ->tel()
->nullable()
->label('Phone'),
Forms\Components\TextInput::make('sender_email')
->email()
->nullable()
->label('Email'),
Forms\Components\TextInput::make('sender_address')
->nullable()
->label('Address'),
Forms\Components\TextInput::make('sender_city')
->nullable()
->label('City'),
Forms\Components\TextInput::make('sender_zip')
->nullable()
->label('ZIP'),
Forms\Components\TextInput::make('sender_id_number')
->nullable()
->label('ID Number'),
])->columns(4), ])->columns(4),
Forms\Components\Section::make('Receiver Info') Forms\Components\Section::make('Receiver Info')
->schema([ ->schema([
Forms\Components\TextInput::make('receiver_name')->nullable()->label('Name'), Forms\Components\TextInput::make('receiver_name')
Forms\Components\TextInput::make('receiver_company')->nullable()->label('Company'), ->nullable()
Forms\Components\TextInput::make('receiver_phone')->tel()->nullable()->label('Phone'), ->label('Name'),
Forms\Components\TextInput::make('receiver_email')->email()->nullable()->label('Email'), Forms\Components\TextInput::make('receiver_company')
Forms\Components\TextInput::make('receiver_address')->nullable()->label('Address'), ->nullable()
Forms\Components\TextInput::make('receiver_city')->nullable()->label('City'), ->label('Company'),
Forms\Components\TextInput::make('receiver_zip')->nullable()->label('ZIP'), Forms\Components\TextInput::make('receiver_phone')
Forms\Components\TextInput::make('receiver_id_number')->nullable()->label('ID Number'), ->tel()
->nullable()
->label('Phone'),
Forms\Components\TextInput::make('receiver_email')
->email()
->nullable()
->label('Email'),
Forms\Components\TextInput::make('receiver_address')
->nullable()
->label('Address'),
Forms\Components\TextInput::make('receiver_city')
->nullable()
->label('City'),
Forms\Components\TextInput::make('receiver_zip')
->nullable()
->label('ZIP'),
Forms\Components\TextInput::make('receiver_id_number')
->nullable()
->label('ID Number'),
])->columns(4), ])->columns(4),
Forms\Components\Section::make('Customs Items') Forms\Components\Section::make('Customs Items')
@ -161,18 +262,41 @@ class ShipmentResource extends Resource
{ {
return $table return $table
->columns([ ->columns([
Tables\Columns\TextColumn::make('awb_no')->searchable()->label('AWB No.')->sortable(), Tables\Columns\TextColumn::make('awb_no')
Tables\Columns\TextColumn::make('direction')->badge()->color(fn (\App\Enums\ShipmentDirection $state): string => match ($state->value) { ->searchable()
'import' => 'success', ->label('AWB No.')
'export' => 'info', ->sortable(),
default => 'gray', Tables\Columns\TextColumn::make('direction')
})->label('Direction'), ->badge()
Tables\Columns\TextColumn::make('type')->badge()->label('Type'), ->color(fn (\App\Enums\ShipmentDirection $state): string => match ($state->value) {
Tables\Columns\TextColumn::make('status')->badge()->searchable()->label('Status'), 'import' => 'success',
Tables\Columns\TextColumn::make('sender_name')->searchable()->toggleable()->label('Sender'), 'export' => 'info',
Tables\Columns\TextColumn::make('receiver_name')->searchable()->toggleable()->label('Receiver'), default => 'gray',
Tables\Columns\TextColumn::make('total_fee')->money('IRR')->sortable()->label('Total Fee'), })
Tables\Columns\TextColumn::make('created_at')->dateTime()->sortable()->toggleable(isToggledHiddenByDefault: true), ->label('Direction'),
Tables\Columns\TextColumn::make('type')
->badge()
->label('Type'),
Tables\Columns\TextColumn::make('status')
->badge()
->searchable()
->label('Status'),
Tables\Columns\TextColumn::make('sender_name')
->searchable()
->toggleable()
->label('Sender'),
Tables\Columns\TextColumn::make('receiver_name')
->searchable()
->toggleable()
->label('Receiver'),
Tables\Columns\TextColumn::make('total_fee')
->money('IRR')
->sortable()
->label('Total Fee'),
Tables\Columns\TextColumn::make('created_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
]) ])
->filters([ ->filters([
Tables\Filters\SelectFilter::make('status') Tables\Filters\SelectFilter::make('status')
@ -192,23 +316,83 @@ class ShipmentResource extends Resource
'PARCEL' => 'Parcel', 'PARCEL' => 'Parcel',
]), ]),
Tables\Filters\SelectFilter::make('direction') Tables\Filters\SelectFilter::make('direction')
->options(['export' => 'Export', 'import' => 'Import']), ->options([
'export' => 'Export',
'import' => 'Import'
]),
]) ])
->actions([ ->actions([
Tables\Actions\ViewAction::make(), Tables\Actions\ViewAction::make(),
Tables\Actions\EditAction::make(), Tables\Actions\EditAction::make(),
]) ])
->headerActions([ ->headerActions([
ExportAction::make() Action::make('exportCsv')
->label('خروجی Excel') ->label('خروجی CSV')
->icon('heroicon-o-arrow-down-tray') ->icon('heroicon-o-arrow-down-tray')
->color('success') ->color('success')
->export(fn ($query) => new ShipmentsExport([ ->action(function () {
'status' => request()->input('filters.status'), return response()->streamDownload(function () {
'type' => request()->input('filters.type'), $csv = fopen('php://output', 'w');
'direction' => request()->input('filters.direction'),
])) // BOM برای پشتیبانی از فارسی در Excel
->fileName('shipments_' . now()->format('Y-m-d_H-i')), fwrite($csv, "\xEF\xBB\xBF");
// Header
fputcsv($csv, [
'AWB No',
'Direction',
'Type',
'Status',
'From Country',
'To Country',
'Weight (kg)',
'Chargeable Weight (kg)',
'Shipping Price (AED)',
'Extra Service (AED)',
'Packing Cost (IRR)',
'Total Fee (IRR)',
'Net Rial (IRR)',
'Sender Name',
'Sender Phone',
'Receiver Name',
'Receiver Phone',
'Created At'
]);
// Data
Shipment::query()
->with(['fromCountry', 'toCountry'])
->orderBy('created_at', 'desc')
->chunk(500, function ($shipments) use ($csv) {
foreach ($shipments as $s) {
fputcsv($csv, [
$s->awb_no,
$s->direction?->value ?? '',
$s->type?->value ?? '',
$s->status?->value ?? '',
$s->fromCountry?->name ?? '',
$s->toCountry?->name ?? '',
$s->weight,
$s->chargeable_weight,
$s->shipping_price,
$s->extra_service,
$s->packing_cost,
$s->total_fee,
$s->net_rial,
$s->sender_name,
$s->sender_phone,
$s->receiver_name,
$s->receiver_phone,
$s->created_at?->format('Y-m-d H:i'),
]);
}
});
fclose($csv);
}, 'shipments_' . now()->format('Y-m-d_H-i') . '.csv', [
'Content-Type' => 'text/csv; charset=UTF-8',
]);
}),
]) ])
->bulkActions([ ->bulkActions([
Tables\Actions\BulkActionGroup::make([ Tables\Actions\BulkActionGroup::make([
@ -220,8 +404,8 @@ class ShipmentResource extends Resource
public static function getRelations(): array public static function getRelations(): array
{ {
return [ return [
ShipmentResource\RelationManagers\CarrierMappingsRelationManager::class, RelationManagers\CarrierMappingsRelationManager::class,
ShipmentResource\RelationManagers\TrackingEventsRelationManager::class, RelationManagers\TrackingEventsRelationManager::class,
]; ];
} }
@ -234,4 +418,4 @@ class ShipmentResource extends Resource
'edit' => Pages\EditShipment::route('/{record}/edit'), 'edit' => Pages\EditShipment::route('/{record}/edit'),
]; ];
} }
} }

View File

@ -12,56 +12,66 @@ use Filament\Forms\Form;
use Filament\Resources\Resource; use Filament\Resources\Resource;
use Filament\Tables; use Filament\Tables;
use Filament\Tables\Table; use Filament\Tables\Table;
use App\Exports\WalletTransactionsExport; use Filament\Tables\Actions\Action;
use Filament\Tables\Actions\ExportAction;
use Maatwebsite\Excel\Facades\Excel;
class WalletTransactionResource extends Resource class WalletTransactionResource extends Resource
{ {
protected static ?string $model = WalletTransaction::class; protected static ?string $model = WalletTransaction::class;
protected static ?string $navigationIcon = 'heroicon-o-arrows-right-left';
protected static ?string $navigationLabel = 'تراکنش‌ها'; protected static ?string $navigationIcon = 'heroicon-o-banknotes';
protected static ?string $navigationLabel = 'تراکنش‌های کیف پول';
protected static ?string $navigationGroup = 'مالی'; protected static ?string $navigationGroup = 'مالی';
protected static ?int $navigationSort = 2; protected static ?int $navigationSort = 2;
protected static ?string $modelLabel = 'تراکنش';
protected static ?string $pluralModelLabel = 'تراکنش‌ها';
public static function form(Form $form): Form public static function form(Form $form): Form
{ {
return $form->schema([ return $form
Forms\Components\Section::make('اطلاعات تراکنش') ->schema([
->schema([ Forms\Components\Section::make('اطلاعات تراکنش')
Forms\Components\Select::make('wallet_id') ->schema([
->relationship('wallet', 'id') Forms\Components\Select::make('wallet_id')
->searchable() ->relationship('wallet', 'id')
->preload() ->required()
->required() ->searchable()
->label('کیف پول'), ->preload()
Forms\Components\TextInput::make('amount') ->label('کیف پول'),
->numeric() Forms\Components\Select::make('type')
->suffix('ریال') ->options(collect(TransactionType::cases())->mapWithKeys(
->required() fn($case) => [$case->value => $case->label()]
->label('مبلغ'), ))
Forms\Components\Select::make('type') ->required()
->options(TransactionType::class) ->label('نوع تراکنش'),
->required() Forms\Components\TextInput::make('amount')
->label('نوع'), ->required()
Forms\Components\Select::make('status') ->numeric()
->options(TransactionStatus::class) ->prefix('ریال')
->required() ->label('مبلغ'),
->label('وضعیت'), Forms\Components\Select::make('status')
Forms\Components\Select::make('gateway') ->options(collect(TransactionStatus::cases())->mapWithKeys(
->options(PaymentGateway::class) fn($case) => [$case->value => $case->label()]
->label('درگاه'), ))
Forms\Components\TextInput::make('gateway_reference_id') ->default(TransactionStatus::PENDING->value)
->label('کد پیگیری'), ->required()
Forms\Components\Textarea::make('description') ->label('وضعیت'),
->label('توضیحات') Forms\Components\Select::make('gateway')
->maxLength(1000), ->options(collect(PaymentGateway::cases())->mapWithKeys(
Forms\Components\Textarea::make('admin_notes') fn($case) => [$case->value => $case->label()]
->label('یادداشت ادمین') ))
->maxLength(2000), ->label('درگاه پرداخت'),
]) Forms\Components\TextInput::make('gateway_reference_id')
->columns(2), ->label('کد پیگیری درگاه'),
]); Forms\Components\Textarea::make('description')
->label('توضیحات')
->columnSpanFull(),
Forms\Components\Textarea::make('admin_notes')
->label('یادداشت ادمین')
->columnSpanFull(),
])->columns(2),
]);
} }
public static function table(Table $table): Table public static function table(Table $table): Table
@ -70,96 +80,141 @@ class WalletTransactionResource extends Resource
->columns([ ->columns([
Tables\Columns\TextColumn::make('id') Tables\Columns\TextColumn::make('id')
->label('شناسه') ->label('شناسه')
->sortable(), ->sortable()
->searchable(),
Tables\Columns\TextColumn::make('wallet.user.name') Tables\Columns\TextColumn::make('wallet.user.name')
->label('کاربر') ->label('کاربر')
->searchable(), ->searchable()
Tables\Columns\TextColumn::make('amount')
->label('مبلغ')
->money('IRR', divideBy: 1)
->color(fn ($record) => $record->amount >= 0 ? 'success' : 'danger')
->sortable(), ->sortable(),
Tables\Columns\BadgeColumn::make('type') Tables\Columns\TextColumn::make('type')
->label('نوع') ->badge()
->getStateUsing(fn ($record) => $record->type->label()) ->color(fn (TransactionType $state): string => $state->color())
->colors([ ->formatStateUsing(fn (TransactionType $state): string => $state->label())
'success' => TransactionType::DEPOSIT, ->label('نوع'),
'danger' => TransactionType::WITHDRAWAL, Tables\Columns\TextColumn::make('amount')
'warning' => TransactionType::ORDER_PAYMENT, ->money('IRR')
'info' => TransactionType::REFUND, ->sortable()
]), ->label('مبلغ'),
Tables\Columns\BadgeColumn::make('status') Tables\Columns\TextColumn::make('status')
->label('وضعیت') ->badge()
->getStateUsing(fn ($record) => $record->status->label()) ->color(fn (TransactionStatus $state): string => $state->color())
->colors([ ->formatStateUsing(fn (TransactionStatus $state): string => $state->label())
'success' => TransactionStatus::COMPLETED, ->label('وضعیت'),
'warning' => TransactionStatus::PENDING, Tables\Columns\TextColumn::make('gateway')
'danger' => TransactionStatus::FAILED, ->badge()
'info' => TransactionStatus::REFUNDED, ->color('info')
]), ->label('درگاه'),
Tables\Columns\BadgeColumn::make('gateway')
->label('درگاه')
->getStateUsing(fn ($record) => $record->gateway?->label() ?? '-')
->colors([
'primary' => PaymentGateway::ZARINPAL,
'success' => PaymentGateway::MANUAL,
'gray' => PaymentGateway::SYSTEM,
]),
Tables\Columns\TextColumn::make('gateway_reference_id') Tables\Columns\TextColumn::make('gateway_reference_id')
->label('کد پیگیری') ->label('کد پیگیری')
->searchable() ->searchable()
->toggleable(), ->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('description') Tables\Columns\TextColumn::make('description')
->label('توضیحات') ->label('توضیحات')
->limit(50) ->limit(50)
->toggleable(), ->toggleable(),
Tables\Columns\TextColumn::make('creator.name')
->label('ایجادکننده')
->toggleable(),
Tables\Columns\TextColumn::make('created_at') Tables\Columns\TextColumn::make('created_at')
->dateTime('Y/m/d H:i', 'Asia/Tehran') ->dateTime('Y/m/d H:i')
->label('تاریخ') ->sortable()
->sortable(), ->label('تاریخ'),
]) ])
->defaultSort('created_at', 'desc')
->filters([ ->filters([
Tables\Filters\SelectFilter::make('type') Tables\Filters\SelectFilter::make('type')
->options(TransactionType::class) ->options(collect(TransactionType::cases())->mapWithKeys(
fn($case) => [$case->value => $case->label()]
))
->label('نوع تراکنش'), ->label('نوع تراکنش'),
Tables\Filters\SelectFilter::make('status') Tables\Filters\SelectFilter::make('status')
->options(TransactionStatus::class) ->options(collect(TransactionStatus::cases())->mapWithKeys(
fn($case) => [$case->value => $case->label()]
))
->label('وضعیت'), ->label('وضعیت'),
Tables\Filters\SelectFilter::make('gateway') Tables\Filters\SelectFilter::make('gateway')
->options(PaymentGateway::class) ->options(collect(PaymentGateway::cases())->mapWithKeys(
fn($case) => [$case->value => $case->label()]
))
->label('درگاه'), ->label('درگاه'),
Tables\Filters\Filter::make('created_at')
->form([
Forms\Components\DatePicker::make('created_from')->label('از تاریخ'),
Forms\Components\DatePicker::make('created_until')->label('تا تاریخ'),
])
->query(function ($query, array $data) {
return $query
->when($data['created_from'], fn($q, $date) => $q->whereDate('created_at', '>=', $date))
->when($data['created_until'], fn($q, $date) => $q->whereDate('created_at', '<=', $date));
}),
]) ])
->actions([ ->actions([
Tables\Actions\ViewAction::make(), Tables\Actions\ViewAction::make(),
Tables\Actions\EditAction::make(),
]) ])
->headerActions([ ->headerActions([
ExportAction::make() Action::make('exportCsv')
->label('خروجی Excel') ->label('خروجی CSV')
->icon('heroicon-o-arrow-down-tray') ->icon('heroicon-o-arrow-down-tray')
->color('success') ->color('success')
->export(fn ($query) => new WalletTransactionsExport([ ->action(function () {
'type' => request()->input('filters.type'), return response()->streamDownload(function () {
'status' => request()->input('filters.status'), $csv = fopen('php://output', 'w');
'gateway' => request()->input('filters.gateway'), fwrite($csv, "\xEF\xBB\xBF");
]))
->fileName('transactions_' . now()->format('Y-m-d_H-i')), fputcsv($csv, [
'شناسه', 'کاربر', 'ایمیل', 'نوع تراکنش', 'مبلغ (ریال)',
'وضعیت', 'درگاه', 'کد پیگیری', 'توضیحات', 'یادداشت ادمین', 'تاریخ'
]);
WalletTransaction::query()
->with(['wallet.user'])
->orderBy('created_at', 'desc')
->chunk(500, function ($transactions) use ($csv) {
foreach ($transactions as $t) {
fputcsv($csv, [
$t->id,
$t->wallet?->user?->name ?? '',
$t->wallet?->user?->email ?? '',
$t->type?->label() ?? '',
$t->amount,
$t->status?->label() ?? '',
$t->gateway?->label() ?? '',
$t->gateway_reference_id ?? '',
$t->description ?? '',
$t->admin_notes ?? '',
$t->created_at?->format('Y-m-d H:i:s'),
]);
}
});
fclose($csv);
}, 'wallet-transactions_' . now()->format('Y-m-d_H-i') . '.csv', [
'Content-Type' => 'text/csv; charset=UTF-8',
]);
}),
]) ])
->bulkActions([ ->bulkActions([
Tables\Actions\BulkActionGroup::make([ Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(), Tables\Actions\DeleteBulkAction::make(),
]), ]),
]); ])
->defaultSort('created_at', 'desc');
}
public static function getRelations(): array
{
return [
//
];
} }
public static function getPages(): array public static function getPages(): array
{ {
return [ return [
'index' => Pages\ListWalletTransactions::route('/'), 'index' => Pages\ListWalletTransactions::route('/'),
'create' => Pages\CreateWalletTransaction::route('/create'),
'view' => Pages\ViewWalletTransaction::route('/{record}'), 'view' => Pages\ViewWalletTransaction::route('/{record}'),
'edit' => Pages\EditWalletTransaction::route('/{record}/edit'),
]; ];
} }
} }

View File

@ -0,0 +1,11 @@
<?php
namespace App\Filament\Resources\WalletTransactionResource\Pages;
use App\Filament\Resources\WalletTransactionResource;
use Filament\Resources\Pages\CreateRecord;
class CreateWalletTransaction extends CreateRecord
{
protected static string $resource = WalletTransactionResource::class;
}

View File

@ -0,0 +1,20 @@
<?php
namespace App\Filament\Resources\WalletTransactionResource\Pages;
use App\Filament\Resources\WalletTransactionResource;
use Filament\Actions;
use Filament\Resources\Pages\EditRecord;
class EditWalletTransaction extends EditRecord
{
protected static string $resource = WalletTransactionResource::class;
protected function getHeaderActions(): array
{
return [
Actions\ViewAction::make(),
Actions\DeleteAction::make(),
];
}
}