form->fill(); } public function form(Form $form): Form { return $form ->schema([ Forms\Components\Section::make('فیلترهای گزارش') ->schema([ Forms\Components\Select::make('report_type') ->label('نوع گزارش') ->options([ 'transactions' => 'تراکنش‌های کیف پول', 'shipments' => 'مرسولات', 'financial_summary' => 'خلاصه مالی', ]) ->required() ->reactive() ->default('transactions'), Forms\Components\DatePicker::make('from_date') ->label('از تاریخ') ->required() ->default(now()->subMonth()), Forms\Components\DatePicker::make('to_date') ->label('تا تاریخ') ->required() ->default(now()), Forms\Components\Select::make('transaction_type') ->label('نوع تراکنش') ->options([ 'deposit' => 'واریزی', 'withdrawal' => 'برداشت', 'order_payment' => 'پرداخت سفارش', 'refund' => 'بازگشت وجه', ]) ->visible(fn ($get) => $get('report_type') === 'transactions') ->placeholder('همه'), Forms\Components\Select::make('shipment_status') ->label('وضعیت مرسوله') ->options([ 'processed' => 'ثبت شده', 'picked_up' => 'تحویل به پست', 'in_transit' => 'در حال حمل', 'out_for_delivery' => 'آماده تحویل', 'delivered' => 'تحویل داده شده', 'failed' => 'ناموفق', 'returned' => 'بازگشته', ]) ->visible(fn ($get) => $get('report_type') === 'shipments') ->placeholder('همه'), ]) ->columns(2), Forms\Components\Section::make('عملیات') ->schema([ Forms\Components\Actions::make([ Forms\Components\Actions\Action::make('generate') ->label('تولید گزارش') ->icon('heroicon-o-eye') ->color('primary') ->action('generateReport'), Forms\Components\Actions\Action::make('export_excel') ->label('خروجی Excel') ->icon('heroicon-o-arrow-down-tray') ->color('success') ->action('exportExcel') ->visible(fn ($get) => $get('report_type') !== 'financial_summary'), ]) ->fullWidth(), ]), ]) ->statePath('data'); } public function generateReport(): void { $this->validate(); $type = $this->data['report_type']; $fromDate = $this->data['from_date']; $toDate = $this->data['to_date']; switch ($type) { case 'transactions': $this->generateTransactionsReport($fromDate, $toDate); break; case 'shipments': $this->generateShipmentsReport($fromDate, $toDate); break; case 'financial_summary': $this->generateFinancialSummary($fromDate, $toDate); break; } } private function generateTransactionsReport($fromDate, $toDate): void { $query = DB::table('wallet_transactions') ->join('wallets', 'wallet_transactions.wallet_id', '=', 'wallets.id') ->join('users', 'wallets.user_id', '=', 'users.id') ->select( 'wallet_transactions.id', 'users.name as user_name', 'users.email as user_email', 'wallet_transactions.amount', 'wallet_transactions.type', 'wallet_transactions.status', 'wallet_transactions.gateway', 'wallet_transactions.description', 'wallet_transactions.created_at' ) ->whereBetween('wallet_transactions.created_at', [$fromDate, $toDate . ' 23:59:59']) ->orderByDesc('wallet_transactions.created_at'); if (!empty($this->data['transaction_type'])) { $query->where('wallet_transactions.type', $this->data['transaction_type']); } $this->reportData = [ 'type' => 'transactions', 'data' => $query->get(), 'summary' => [ 'total_count' => $query->count(), 'total_amount' => $query->sum('amount'), 'deposits' => $query->where('type', 'deposit')->sum('amount'), 'withdrawals' => $query->whereIn('type', ['withdrawal', 'order_payment'])->sum('amount'), ], ]; } private function generateShipmentsReport($fromDate, $toDate): void { $query = DB::table('shipments') ->join('countries as from_country', 'shipments.from_country_id', '=', 'from_country.id') ->join('countries as to_country', 'shipments.to_country_id', '=', 'to_country.id') ->select( 'shipments.awb_no', 'shipments.direction', 'shipments.type', 'shipments.status', 'from_country.name as from_country', 'to_country.name as to_country', 'shipments.weight', 'shipments.chargeable_weight', 'shipments.shipping_price', 'shipments.total_fee', 'shipments.sender_name', 'shipments.receiver_name', 'shipments.created_at' ) ->whereBetween('shipments.created_at', [$fromDate, $toDate . ' 23:59:59']) ->orderByDesc('shipments.created_at'); if (!empty($this->data['shipment_status'])) { $query->where('shipments.status', $this->data['shipment_status']); } $this->reportData = [ 'type' => 'shipments', 'data' => $query->get(), 'summary' => [ 'total_count' => $query->count(), 'total_fee' => $query->sum('total_fee'), 'total_weight' => $query->sum('chargeable_weight'), ], ]; } private function generateFinancialSummary($fromDate, $toDate): void { // Total deposits $deposits = DB::table('wallet_transactions') ->where('type', 'deposit') ->where('status', 'completed') ->whereBetween('created_at', [$fromDate, $toDate . ' 23:59:59']) ->sum('amount'); // Total withdrawals/order payments $withdrawals = DB::table('wallet_transactions') ->whereIn('type', ['withdrawal', 'order_payment']) ->where('status', 'completed') ->whereBetween('created_at', [$fromDate, $toDate . ' 23:59:59']) ->sum('amount'); // Total shipments revenue $shipmentsRevenue = DB::table('shipments') ->whereBetween('created_at', [$fromDate, $toDate . ' 23:59:59']) ->sum('total_fee'); // Total discount codes used $discounts = DB::table('discount_codes') ->where('is_active', true) ->whereBetween('updated_at', [$fromDate, $toDate . ' 23:59:59']) ->sum('used_count'); // Wallet balances $totalBalance = DB::table('wallets')->sum('balance'); $totalDeposited = DB::table('wallets')->sum('total_deposited'); $totalWithdrawn = DB::table('wallets')->sum('total_withdrawn'); $this->reportData = [ 'type' => 'financial_summary', 'summary' => [ 'deposits' => $deposits, 'withdrawals' => abs($withdrawals), 'shipments_revenue' => $shipmentsRevenue, 'discounts_used' => $discounts, 'total_balance' => $totalBalance, 'total_deposited' => $totalDeposited, 'total_withdrawn' => $totalWithdrawn, 'net_profit' => $shipmentsRevenue - $withdrawals, ], ]; } public function exportExcel(): \Symfony\Component\HttpFoundation\BinaryFileResponse { $this->validate(); $type = $this->data['report_type']; $filters = [ 'from_date' => $this->data['from_date'], 'to_date' => $this->data['to_date'], ]; if ($type === 'transactions') { $filters['type'] = $this->data['transaction_type'] ?? null; $export = new WalletTransactionsExport($filters); $fileName = 'transactions_' . now()->format('Y-m-d_H-i') . '.xlsx'; } elseif ($type === 'shipments') { $filters['status'] = $this->data['shipment_status'] ?? null; $export = new ShipmentsExport($filters); $fileName = 'shipments_' . now()->format('Y-m-d_H-i') . '.xlsx'; } else { Notification::make() ->title('خطا') ->body('برای خلاصه مالی خروجی Excel موجود نیست.') ->danger() ->send(); return redirect()->back(); } return Excel::download($export, $fileName); } }