namespace App\Http\Controllers\Admin; use App\Http\Controllers\Controller; use App\Models\Order; use App\Models\User; use App\Models\Transaction; use App\Models\Service; use App\Exports\RevenueReportExport; use App\Exports\OrdersReportExport; use App\Exports\ServicesReportExport; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; use Maatwebsite\Excel\Facades\Excel; use Carbon\Carbon; class ReportController extends Controller { public function revenue(Request $request) { $period = $request->get('period', 'month'); $startDate = $this->getStartDate($period); $endDate = Carbon::now(); // Daily revenue for chart $dailyRevenue = Order::where('status', 'completed') ->whereBetween('created_at', [$startDate, $endDate]) ->select( DB::raw('DATE(created_at) as date'), DB::raw('COUNT(*) as total_orders'), DB::raw('SUM(price) as revenue'), DB::raw('SUM(profit) as profit') ) ->groupBy('date') ->orderBy('date') ->get(); // Summary stats $summary = [ 'total_revenue' => Order::where('status', 'completed') ->whereBetween('created_at', [$startDate, $endDate]) ->sum('price'), 'total_profit' => Order::where('status', 'completed') ->whereBetween('created_at', [$startDate, $endDate]) ->sum('profit'), 'total_orders' => Order::where('status', 'completed') ->whereBetween('created_at', [$startDate, $endDate]) ->count(), 'avg_order_value' => Order::where('status', 'completed') ->whereBetween('created_at', [$startDate, $endDate]) ->avg('price'), ]; // Revenue by payment method $revenueByMethod = Transaction::where('status', 'completed') ->where('type', 'deposit') ->whereBetween('created_at', [$startDate, $endDate]) ->select('payment_method', DB::raw('SUM(amount) as total')) ->groupBy('payment_method') ->get(); // Revenue by service category $revenueByCategory = Order::where('orders.status', 'completed') ->whereBetween('orders.created_at', [$startDate, $endDate]) ->join('services', 'orders.service_id', '=', 'services.id') ->join('categories', 'services.category_id', '=', 'categories.id') ->select('categories.name', DB::raw('SUM(orders.price) as total')) ->groupBy('categories.id', 'categories.name') ->get(); return view('admin.reports.revenue', compact( 'dailyRevenue', 'summary', 'revenueByMethod', 'revenueByCategory', 'period' )); } public function orders(Request $request) { $query = Order::with(['user', 'service', 'service.category']); // Date range filter if ($request->has('date_from')) { $query->whereDate('created_at', '>=', $request->date_from); } if ($request->has('date_to')) { $query->whereDate('created_at', '<=', $request->date_to); } // Status filter if ($request->has('status') && $request->status != 'all') { $query->where('status', $request->status); } // Service filter if ($request->has('service_id') && $request->service_id != 'all') { $query->where('service_id', $request->service_id); } $orders = $query->latest()->paginate(50); $services = Service::where('status', 'active')->orderBy('name')->get(); $stats = [ 'total' => $query->count(), 'total_revenue' => $query->sum('price'), 'total_profit' => $query->sum('profit'), 'avg_order' => $query->avg('price'), ]; return view('admin.reports.orders', compact('orders', 'services', 'stats')); } public function services(Request $request) { $period = $request->get('period', 'month'); $startDate = $this->getStartDate($period); $endDate = Carbon::now(); $services = Service::with(['category']) ->withCount(['orders' => function($query) use ($startDate, $endDate) { $query->whereBetween('created_at', [$startDate, $endDate]); }]) ->withSum(['orders' => function($query) use ($startDate, $endDate) { $query->where('status', 'completed') ->whereBetween('created_at', [$startDate, $endDate]); }], 'price') ->withSum(['orders' => function($query) use ($startDate, $endDate) { $query->where('status', 'completed') ->whereBetween('created_at', [$startDate, $endDate]); }], 'profit') ->orderByDesc('orders_sum_price') ->get(); $topServices = $services->take(10); $bottomServices = $services->filter(function($service) { return $service->orders_count > 0; })->sortBy('orders_count')->take(10); $stats = [ 'total_services' => Service::count(), 'active_services' => Service::where('status', 'active')->count(), 'services_with_orders' => $services->filter(function($s) { return $s->orders_count > 0; })->count(), ]; return view('admin.reports.services', compact( 'services', 'topServices', 'bottomServices', 'stats', 'period' )); } public function users(Request $request) { $period = $request->get('period', 'month'); $startDate = $this->getStartDate($period); $endDate = Carbon::now(); $users = User::withCount(['orders' => function($query) use ($startDate, $endDate) { $query->whereBetween('created_at', [$startDate, $endDate]); }]) ->withSum(['orders' => function($query) use ($startDate, $endDate) { $query->where('status', 'completed') ->whereBetween('created_at', [$startDate, $endDate]); }], 'price') ->withSum(['transactions' => function($query) use ($startDate, $endDate) { $query->where('type', 'deposit') ->where('status', 'completed') ->whereBetween('created_at', [$startDate, $endDate]); }], 'amount') ->orderByDesc('orders_sum_price') ->limit(100) ->get(); $stats = [ 'total_users' => User::count(), 'new_users' => User::whereBetween('created_at', [$startDate, $endDate])->count(), 'active_users' => User::where('last_login_at', '>=', $startDate)->count(), 'users_with_orders' => $users->filter(function($u) { return $u->orders_count > 0; })->count(), ]; return view('admin.reports.users', compact('users', 'stats', 'period')); } public function export(Request $request) { $request->validate([ 'type' => 'required|in:revenue,orders,services,users', 'format' => 'required|in:csv,xlsx', 'date_from' => 'nullable|date', 'date_to' => 'nullable|date', ]); $filename = $request->type . '_report_' . now()->format('Y_m_d_His'); // Log activity auth()->guard('admin')->user()->logActivity( 'Exported report: ' . $request->type, ['format' => $request->format, 'date_from' => $request->date_from, 'date_to' => $request->date_to] ); switch ($request->type) { case 'revenue': $export = new RevenueReportExport($request); break; case 'orders': $export = new OrdersReportExport($request); break; case 'services': $export = new ServicesReportExport($request); break; default: return back()->with('error', 'Invalid report type.'); } if ($request->format == 'csv') { return Excel::download($export, $filename . '.csv'); } return Excel::download($export, $filename . '.xlsx'); } protected function getStartDate($period) { switch ($period) { case 'week': return Carbon::now()->subDays(7); case 'month': return Carbon::now()->subDays(30); case 'quarter': return Carbon::now()->subDays(90); case 'year': return Carbon::now()->subDays(365); default: return Carbon::now()->subDays(30); } } }