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:
parent
810004aab1
commit
bc52e94dc3
@ -3,14 +3,14 @@
|
||||
namespace App\Filament\Resources;
|
||||
|
||||
use App\Filament\Resources\ShipmentResource\Pages;
|
||||
use App\Filament\Resources\ShipmentResource\RelationManagers;
|
||||
use App\Models\Shipment;
|
||||
use Filament\Forms;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Table;
|
||||
use App\Exports\ShipmentsExport;
|
||||
use Filament\Tables\Actions\ExportAction;
|
||||
use Filament\Tables\Actions\Action;
|
||||
|
||||
class ShipmentResource extends Resource
|
||||
{
|
||||
@ -33,7 +33,10 @@ class ShipmentResource extends Resource
|
||||
->unique(ignoreRecord: true)
|
||||
->label('AWB No.'),
|
||||
Forms\Components\Select::make('direction')
|
||||
->options(['export' => 'Export', 'import' => 'Import'])
|
||||
->options([
|
||||
'export' => 'Export',
|
||||
'import' => 'Import'
|
||||
])
|
||||
->required(),
|
||||
Forms\Components\Select::make('type')
|
||||
->options([
|
||||
@ -54,8 +57,12 @@ class ShipmentResource extends Resource
|
||||
])
|
||||
->default('processed')
|
||||
->required(),
|
||||
Forms\Components\TextInput::make('reason_for_export')->nullable()->label('Reason for Export'),
|
||||
Forms\Components\TextInput::make('forwarder')->nullable()->label('Forwarder'),
|
||||
Forms\Components\TextInput::make('reason_for_export')
|
||||
->nullable()
|
||||
->label('Reason for Export'),
|
||||
Forms\Components\TextInput::make('forwarder')
|
||||
->nullable()
|
||||
->label('Forwarder'),
|
||||
Forms\Components\Select::make('from_country_id')
|
||||
->relationship('fromCountry', 'name')
|
||||
->searchable()
|
||||
@ -70,49 +77,143 @@ class ShipmentResource extends Resource
|
||||
|
||||
Forms\Components\Section::make('Weight & Dimensions')
|
||||
->schema([
|
||||
Forms\Components\TextInput::make('weight')->numeric()->nullable()->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)'),
|
||||
Forms\Components\TextInput::make('weight')
|
||||
->numeric()
|
||||
->nullable()
|
||||
->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),
|
||||
|
||||
Forms\Components\Section::make('Financial Info')
|
||||
->schema([
|
||||
Forms\Components\TextInput::make('shipping_price')->numeric()->nullable()->prefix('درهم')->label('Shipping Price'),
|
||||
Forms\Components\TextInput::make('extra_service')->numeric()->default(0)->prefix('درهم')->label('Extra Service'),
|
||||
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'),
|
||||
Forms\Components\TextInput::make('shipping_price')
|
||||
->numeric()
|
||||
->nullable()
|
||||
->prefix('درهم')
|
||||
->label('Shipping Price'),
|
||||
Forms\Components\TextInput::make('extra_service')
|
||||
->numeric()
|
||||
->default(0)
|
||||
->prefix('درهم')
|
||||
->label('Extra Service'),
|
||||
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),
|
||||
|
||||
Forms\Components\Section::make('Sender Info')
|
||||
->schema([
|
||||
Forms\Components\TextInput::make('sender_name')->nullable()->label('Name'),
|
||||
Forms\Components\TextInput::make('sender_company')->nullable()->label('Company'),
|
||||
Forms\Components\TextInput::make('sender_phone')->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'),
|
||||
Forms\Components\TextInput::make('sender_name')
|
||||
->nullable()
|
||||
->label('Name'),
|
||||
Forms\Components\TextInput::make('sender_company')
|
||||
->nullable()
|
||||
->label('Company'),
|
||||
Forms\Components\TextInput::make('sender_phone')
|
||||
->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),
|
||||
|
||||
Forms\Components\Section::make('Receiver Info')
|
||||
->schema([
|
||||
Forms\Components\TextInput::make('receiver_name')->nullable()->label('Name'),
|
||||
Forms\Components\TextInput::make('receiver_company')->nullable()->label('Company'),
|
||||
Forms\Components\TextInput::make('receiver_phone')->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'),
|
||||
Forms\Components\TextInput::make('receiver_name')
|
||||
->nullable()
|
||||
->label('Name'),
|
||||
Forms\Components\TextInput::make('receiver_company')
|
||||
->nullable()
|
||||
->label('Company'),
|
||||
Forms\Components\TextInput::make('receiver_phone')
|
||||
->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),
|
||||
|
||||
Forms\Components\Section::make('Customs Items')
|
||||
@ -161,18 +262,41 @@ class ShipmentResource extends Resource
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('awb_no')->searchable()->label('AWB No.')->sortable(),
|
||||
Tables\Columns\TextColumn::make('direction')->badge()->color(fn (\App\Enums\ShipmentDirection $state): string => match ($state->value) {
|
||||
Tables\Columns\TextColumn::make('awb_no')
|
||||
->searchable()
|
||||
->label('AWB No.')
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('direction')
|
||||
->badge()
|
||||
->color(fn (\App\Enums\ShipmentDirection $state): string => match ($state->value) {
|
||||
'import' => 'success',
|
||||
'export' => 'info',
|
||||
default => 'gray',
|
||||
})->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),
|
||||
})
|
||||
->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([
|
||||
Tables\Filters\SelectFilter::make('status')
|
||||
@ -192,23 +316,83 @@ class ShipmentResource extends Resource
|
||||
'PARCEL' => 'Parcel',
|
||||
]),
|
||||
Tables\Filters\SelectFilter::make('direction')
|
||||
->options(['export' => 'Export', 'import' => 'Import']),
|
||||
->options([
|
||||
'export' => 'Export',
|
||||
'import' => 'Import'
|
||||
]),
|
||||
])
|
||||
->actions([
|
||||
Tables\Actions\ViewAction::make(),
|
||||
Tables\Actions\EditAction::make(),
|
||||
])
|
||||
->headerActions([
|
||||
ExportAction::make()
|
||||
->label('خروجی Excel')
|
||||
Action::make('exportCsv')
|
||||
->label('خروجی CSV')
|
||||
->icon('heroicon-o-arrow-down-tray')
|
||||
->color('success')
|
||||
->export(fn ($query) => new ShipmentsExport([
|
||||
'status' => request()->input('filters.status'),
|
||||
'type' => request()->input('filters.type'),
|
||||
'direction' => request()->input('filters.direction'),
|
||||
]))
|
||||
->fileName('shipments_' . now()->format('Y-m-d_H-i')),
|
||||
->action(function () {
|
||||
return response()->streamDownload(function () {
|
||||
$csv = fopen('php://output', 'w');
|
||||
|
||||
// BOM برای پشتیبانی از فارسی در Excel
|
||||
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([
|
||||
Tables\Actions\BulkActionGroup::make([
|
||||
@ -220,8 +404,8 @@ class ShipmentResource extends Resource
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
ShipmentResource\RelationManagers\CarrierMappingsRelationManager::class,
|
||||
ShipmentResource\RelationManagers\TrackingEventsRelationManager::class,
|
||||
RelationManagers\CarrierMappingsRelationManager::class,
|
||||
RelationManagers\TrackingEventsRelationManager::class,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@ -12,55 +12,65 @@ use Filament\Forms\Form;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Table;
|
||||
use App\Exports\WalletTransactionsExport;
|
||||
use Filament\Tables\Actions\ExportAction;
|
||||
use Maatwebsite\Excel\Facades\Excel;
|
||||
use Filament\Tables\Actions\Action;
|
||||
|
||||
class WalletTransactionResource extends Resource
|
||||
{
|
||||
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 ?int $navigationSort = 2;
|
||||
|
||||
protected static ?string $modelLabel = 'تراکنش';
|
||||
protected static ?string $pluralModelLabel = 'تراکنشها';
|
||||
|
||||
public static function form(Form $form): Form
|
||||
{
|
||||
return $form->schema([
|
||||
return $form
|
||||
->schema([
|
||||
Forms\Components\Section::make('اطلاعات تراکنش')
|
||||
->schema([
|
||||
Forms\Components\Select::make('wallet_id')
|
||||
->relationship('wallet', 'id')
|
||||
->required()
|
||||
->searchable()
|
||||
->preload()
|
||||
->required()
|
||||
->label('کیف پول'),
|
||||
Forms\Components\TextInput::make('amount')
|
||||
->numeric()
|
||||
->suffix('ریال')
|
||||
->required()
|
||||
->label('مبلغ'),
|
||||
Forms\Components\Select::make('type')
|
||||
->options(TransactionType::class)
|
||||
->options(collect(TransactionType::cases())->mapWithKeys(
|
||||
fn($case) => [$case->value => $case->label()]
|
||||
))
|
||||
->required()
|
||||
->label('نوع'),
|
||||
->label('نوع تراکنش'),
|
||||
Forms\Components\TextInput::make('amount')
|
||||
->required()
|
||||
->numeric()
|
||||
->prefix('ریال')
|
||||
->label('مبلغ'),
|
||||
Forms\Components\Select::make('status')
|
||||
->options(TransactionStatus::class)
|
||||
->options(collect(TransactionStatus::cases())->mapWithKeys(
|
||||
fn($case) => [$case->value => $case->label()]
|
||||
))
|
||||
->default(TransactionStatus::PENDING->value)
|
||||
->required()
|
||||
->label('وضعیت'),
|
||||
Forms\Components\Select::make('gateway')
|
||||
->options(PaymentGateway::class)
|
||||
->label('درگاه'),
|
||||
->options(collect(PaymentGateway::cases())->mapWithKeys(
|
||||
fn($case) => [$case->value => $case->label()]
|
||||
))
|
||||
->label('درگاه پرداخت'),
|
||||
Forms\Components\TextInput::make('gateway_reference_id')
|
||||
->label('کد پیگیری'),
|
||||
->label('کد پیگیری درگاه'),
|
||||
Forms\Components\Textarea::make('description')
|
||||
->label('توضیحات')
|
||||
->maxLength(1000),
|
||||
->columnSpanFull(),
|
||||
Forms\Components\Textarea::make('admin_notes')
|
||||
->label('یادداشت ادمین')
|
||||
->maxLength(2000),
|
||||
])
|
||||
->columns(2),
|
||||
->columnSpanFull(),
|
||||
])->columns(2),
|
||||
]);
|
||||
}
|
||||
|
||||
@ -70,96 +80,141 @@ class WalletTransactionResource extends Resource
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('id')
|
||||
->label('شناسه')
|
||||
->sortable(),
|
||||
->sortable()
|
||||
->searchable(),
|
||||
Tables\Columns\TextColumn::make('wallet.user.name')
|
||||
->label('کاربر')
|
||||
->searchable(),
|
||||
Tables\Columns\TextColumn::make('amount')
|
||||
->label('مبلغ')
|
||||
->money('IRR', divideBy: 1)
|
||||
->color(fn ($record) => $record->amount >= 0 ? 'success' : 'danger')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
Tables\Columns\BadgeColumn::make('type')
|
||||
->label('نوع')
|
||||
->getStateUsing(fn ($record) => $record->type->label())
|
||||
->colors([
|
||||
'success' => TransactionType::DEPOSIT,
|
||||
'danger' => TransactionType::WITHDRAWAL,
|
||||
'warning' => TransactionType::ORDER_PAYMENT,
|
||||
'info' => TransactionType::REFUND,
|
||||
]),
|
||||
Tables\Columns\BadgeColumn::make('status')
|
||||
->label('وضعیت')
|
||||
->getStateUsing(fn ($record) => $record->status->label())
|
||||
->colors([
|
||||
'success' => TransactionStatus::COMPLETED,
|
||||
'warning' => TransactionStatus::PENDING,
|
||||
'danger' => TransactionStatus::FAILED,
|
||||
'info' => TransactionStatus::REFUNDED,
|
||||
]),
|
||||
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('type')
|
||||
->badge()
|
||||
->color(fn (TransactionType $state): string => $state->color())
|
||||
->formatStateUsing(fn (TransactionType $state): string => $state->label())
|
||||
->label('نوع'),
|
||||
Tables\Columns\TextColumn::make('amount')
|
||||
->money('IRR')
|
||||
->sortable()
|
||||
->label('مبلغ'),
|
||||
Tables\Columns\TextColumn::make('status')
|
||||
->badge()
|
||||
->color(fn (TransactionStatus $state): string => $state->color())
|
||||
->formatStateUsing(fn (TransactionStatus $state): string => $state->label())
|
||||
->label('وضعیت'),
|
||||
Tables\Columns\TextColumn::make('gateway')
|
||||
->badge()
|
||||
->color('info')
|
||||
->label('درگاه'),
|
||||
Tables\Columns\TextColumn::make('gateway_reference_id')
|
||||
->label('کد پیگیری')
|
||||
->searchable()
|
||||
->toggleable(),
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
Tables\Columns\TextColumn::make('description')
|
||||
->label('توضیحات')
|
||||
->limit(50)
|
||||
->toggleable(),
|
||||
Tables\Columns\TextColumn::make('creator.name')
|
||||
->label('ایجادکننده')
|
||||
->toggleable(),
|
||||
Tables\Columns\TextColumn::make('created_at')
|
||||
->dateTime('Y/m/d H:i', 'Asia/Tehran')
|
||||
->label('تاریخ')
|
||||
->sortable(),
|
||||
->dateTime('Y/m/d H:i')
|
||||
->sortable()
|
||||
->label('تاریخ'),
|
||||
])
|
||||
->defaultSort('created_at', 'desc')
|
||||
->filters([
|
||||
Tables\Filters\SelectFilter::make('type')
|
||||
->options(TransactionType::class)
|
||||
->options(collect(TransactionType::cases())->mapWithKeys(
|
||||
fn($case) => [$case->value => $case->label()]
|
||||
))
|
||||
->label('نوع تراکنش'),
|
||||
|
||||
Tables\Filters\SelectFilter::make('status')
|
||||
->options(TransactionStatus::class)
|
||||
->options(collect(TransactionStatus::cases())->mapWithKeys(
|
||||
fn($case) => [$case->value => $case->label()]
|
||||
))
|
||||
->label('وضعیت'),
|
||||
|
||||
Tables\Filters\SelectFilter::make('gateway')
|
||||
->options(PaymentGateway::class)
|
||||
->options(collect(PaymentGateway::cases())->mapWithKeys(
|
||||
fn($case) => [$case->value => $case->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([
|
||||
Tables\Actions\ViewAction::make(),
|
||||
Tables\Actions\EditAction::make(),
|
||||
])
|
||||
->headerActions([
|
||||
ExportAction::make()
|
||||
->label('خروجی Excel')
|
||||
Action::make('exportCsv')
|
||||
->label('خروجی CSV')
|
||||
->icon('heroicon-o-arrow-down-tray')
|
||||
->color('success')
|
||||
->export(fn ($query) => new WalletTransactionsExport([
|
||||
'type' => request()->input('filters.type'),
|
||||
'status' => request()->input('filters.status'),
|
||||
'gateway' => request()->input('filters.gateway'),
|
||||
]))
|
||||
->fileName('transactions_' . now()->format('Y-m-d_H-i')),
|
||||
->action(function () {
|
||||
return response()->streamDownload(function () {
|
||||
$csv = fopen('php://output', 'w');
|
||||
fwrite($csv, "\xEF\xBB\xBF");
|
||||
|
||||
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([
|
||||
Tables\Actions\BulkActionGroup::make([
|
||||
Tables\Actions\DeleteBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
])
|
||||
->defaultSort('created_at', 'desc');
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => Pages\ListWalletTransactions::route('/'),
|
||||
'create' => Pages\CreateWalletTransaction::route('/create'),
|
||||
'view' => Pages\ViewWalletTransaction::route('/{record}'),
|
||||
'edit' => Pages\EditWalletTransaction::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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(),
|
||||
];
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user