|
|
<?php |
|
|
|
|
|
namespace App\Http\Controllers\Api; |
|
|
|
|
|
use App\Http\Controllers\Controller; |
|
|
use App\Services\AnalyticsService; |
|
|
use Illuminate\Http\Request; |
|
|
use Illuminate\Http\JsonResponse; |
|
|
use Carbon\Carbon; |
|
|
|
|
|
class DashboardController extends Controller |
|
|
{ |
|
|
protected AnalyticsService $analyticsService; |
|
|
|
|
|
public function __construct(AnalyticsService $analyticsService) |
|
|
{ |
|
|
$this->analyticsService = $analyticsService; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function revenue(Request $request): JsonResponse |
|
|
{ |
|
|
$period = $request->get('period', 'daily'); |
|
|
$date = $request->get('date') ? Carbon::parse($request->get('date')) : Carbon::now(); |
|
|
|
|
|
$data = $this->analyticsService->getAggregatedData($period, $date); |
|
|
$todayRevenue = $this->analyticsService->getTodayRevenue(); |
|
|
|
|
|
return response()->json([ |
|
|
'success' => true, |
|
|
'data' => [ |
|
|
'chart_data' => $data, |
|
|
'summary' => $todayRevenue, |
|
|
'period' => $period, |
|
|
'date' => $date->format('Y-m-d') |
|
|
] |
|
|
]); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function profit(Request $request): JsonResponse |
|
|
{ |
|
|
$period = $request->get('period', 'today'); |
|
|
$date = $request->get('date') ? Carbon::parse($request->get('date')) : Carbon::now(); |
|
|
|
|
|
$profitData = $this->analyticsService->getProfitData($period); |
|
|
$chartData = $this->analyticsService->getAggregatedData($period === 'today' ? 'daily' : $period, $date); |
|
|
|
|
|
|
|
|
$formattedChartData = array_map(function ($item) { |
|
|
return [ |
|
|
'label' => $item['hour'] ?? $item['day_name'] ?? $item['day'] ?? $item['date'], |
|
|
'revenue' => $item['revenue'], |
|
|
'profit' => $item['profit'], |
|
|
'profit_margin' => $item['revenue'] > 0 ? (($item['profit'] / $item['revenue']) * 100) : 0 |
|
|
]; |
|
|
}, $chartData); |
|
|
|
|
|
return response()->json([ |
|
|
'success' => true, |
|
|
'data' => [ |
|
|
'chart_data' => $formattedChartData, |
|
|
'summary' => $profitData, |
|
|
'period' => $period, |
|
|
'date' => $date->format('Y-m-d') |
|
|
] |
|
|
]); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function sales(Request $request): JsonResponse |
|
|
{ |
|
|
$limit = $request->get('limit', 10); |
|
|
|
|
|
$topProducts = $this->analyticsService->getTopProducts($limit); |
|
|
$period = $request->get('period', 'daily'); |
|
|
$date = $request->get('date') ? Carbon::parse($request->get('date')) : Carbon::now(); |
|
|
|
|
|
$salesData = $this->analyticsService->getAggregatedData($period, $date); |
|
|
|
|
|
|
|
|
$formattedSalesData = array_map(function ($item) { |
|
|
return [ |
|
|
'label' => $item['hour'] ?? $item['day_name'] ?? $item['day'] ?? $item['date'], |
|
|
'orders' => $item['orders'], |
|
|
'revenue' => $item['revenue'], |
|
|
'avg_order_value' => $item['orders'] > 0 ? ($item['revenue'] / $item['orders']) : 0 |
|
|
]; |
|
|
}, $salesData); |
|
|
|
|
|
return response()->json([ |
|
|
'success' => true, |
|
|
'data' => [ |
|
|
'top_products' => $topProducts, |
|
|
'sales_chart' => $formattedSalesData, |
|
|
'period' => $period, |
|
|
'date' => $date->format('Y-m-d') |
|
|
] |
|
|
]); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function customers(Request $request): JsonResponse |
|
|
{ |
|
|
$customerAnalytics = $this->analyticsService->getCustomerAnalytics(); |
|
|
$period = $request->get('period', 'daily'); |
|
|
$date = $request->get('date') ? Carbon::parse($request->get('date')) : Carbon::now(); |
|
|
|
|
|
$customerData = $this->analyticsService->getAggregatedData($period, $date); |
|
|
|
|
|
|
|
|
$formattedCustomerData = array_map(function ($item) { |
|
|
return [ |
|
|
'label' => $item['hour'] ?? $item['day_name'] ?? $item['day'] ?? $item['date'], |
|
|
'customers' => $item['customers'], |
|
|
'orders' => $item['orders'], |
|
|
'conversion_rate' => $item['customers'] > 0 ? (($item['orders'] / $item['customers']) * 100) : 0 |
|
|
]; |
|
|
}, $customerData); |
|
|
|
|
|
return response()->json([ |
|
|
'success' => true, |
|
|
'data' => [ |
|
|
'analytics' => $customerAnalytics, |
|
|
'chart_data' => $formattedCustomerData, |
|
|
'period' => $period, |
|
|
'date' => $date->format('Y-m-d') |
|
|
] |
|
|
]); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function summary(Request $request): JsonResponse |
|
|
{ |
|
|
$period = $request->get('period', 'daily'); |
|
|
$date = $request->get('date') ? Carbon::parse($request->get('date')) : Carbon::now(); |
|
|
|
|
|
|
|
|
$revenueData = $this->getRevenueForPeriod($period, $date); |
|
|
$profitData = $this->analyticsService->getProfitData($period); |
|
|
$customerAnalytics = $this->analyticsService->getCustomerAnalytics(); |
|
|
$orderStats = $this->getOrdersForPeriod($period, $date); |
|
|
$productStats = $this->analyticsService->getProductStats(); |
|
|
$topProducts = $this->analyticsService->getTopProducts(5); |
|
|
|
|
|
return response()->json([ |
|
|
'success' => true, |
|
|
'data' => [ |
|
|
'revenue' => $revenueData, |
|
|
'profit' => $profitData, |
|
|
'orders' => $orderStats, |
|
|
'customers' => $customerAnalytics, |
|
|
'products' => $productStats, |
|
|
'top_products' => $topProducts, |
|
|
'period' => $period, |
|
|
'date' => $date->format('Y-m-d'), |
|
|
'last_updated' => Carbon::now()->toISOString() |
|
|
] |
|
|
]); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private function getRevenueForPeriod(string $period, Carbon $date): array |
|
|
{ |
|
|
switch ($period) { |
|
|
case 'weekly': |
|
|
$current = \App\Models\Order::whereBetween('created_at', [ |
|
|
$date->copy()->startOfWeek(), |
|
|
$date->copy()->endOfWeek() |
|
|
])->sum('total_amount'); |
|
|
|
|
|
$previous = \App\Models\Order::whereBetween('created_at', [ |
|
|
$date->copy()->subWeek()->startOfWeek(), |
|
|
$date->copy()->subWeek()->endOfWeek() |
|
|
])->sum('total_amount'); |
|
|
break; |
|
|
|
|
|
case 'monthly': |
|
|
$current = \App\Models\Order::whereBetween('created_at', [ |
|
|
$date->copy()->startOfMonth(), |
|
|
$date->copy()->endOfMonth() |
|
|
])->sum('total_amount'); |
|
|
|
|
|
$previous = \App\Models\Order::whereBetween('created_at', [ |
|
|
$date->copy()->subMonth()->startOfMonth(), |
|
|
$date->copy()->subMonth()->endOfMonth() |
|
|
])->sum('total_amount'); |
|
|
break; |
|
|
|
|
|
default: |
|
|
$current = \App\Models\Order::whereDate('created_at', $date)->sum('total_amount'); |
|
|
$previous = \App\Models\Order::whereDate('created_at', $date->copy()->subDay())->sum('total_amount'); |
|
|
break; |
|
|
} |
|
|
|
|
|
$percentageChange = $previous > 0 ? (($current - $previous) / $previous) * 100 : 0; |
|
|
|
|
|
return [ |
|
|
'current' => $current, |
|
|
'previous' => $previous, |
|
|
'percentage_change' => round($percentageChange, 2), |
|
|
'trend' => $percentageChange >= 0 ? 'up' : 'down' |
|
|
]; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private function getOrdersForPeriod(string $period, Carbon $date): array |
|
|
{ |
|
|
switch ($period) { |
|
|
case 'weekly': |
|
|
$current = \App\Models\Order::whereBetween('created_at', [ |
|
|
$date->copy()->startOfWeek(), |
|
|
$date->copy()->endOfWeek() |
|
|
])->count(); |
|
|
|
|
|
$previous = \App\Models\Order::whereBetween('created_at', [ |
|
|
$date->copy()->subWeek()->startOfWeek(), |
|
|
$date->copy()->subWeek()->endOfWeek() |
|
|
])->count(); |
|
|
break; |
|
|
|
|
|
case 'monthly': |
|
|
$current = \App\Models\Order::whereBetween('created_at', [ |
|
|
$date->copy()->startOfMonth(), |
|
|
$date->copy()->endOfMonth() |
|
|
])->count(); |
|
|
|
|
|
$previous = \App\Models\Order::whereBetween('created_at', [ |
|
|
$date->copy()->subMonth()->startOfMonth(), |
|
|
$date->copy()->subMonth()->endOfMonth() |
|
|
])->count(); |
|
|
break; |
|
|
|
|
|
default: |
|
|
$current = \App\Models\Order::whereDate('created_at', $date)->count(); |
|
|
$previous = \App\Models\Order::whereDate('created_at', $date->copy()->subDay())->count(); |
|
|
break; |
|
|
} |
|
|
|
|
|
$percentageChange = $previous > 0 ? (($current - $previous) / $previous) * 100 : 0; |
|
|
|
|
|
return [ |
|
|
'current' => $current, |
|
|
'previous' => $previous, |
|
|
'percentage_change' => round($percentageChange, 2), |
|
|
'trend' => $percentageChange >= 0 ? 'up' : 'down' |
|
|
]; |
|
|
} |
|
|
} |
|
|
|