user()->business_id; $date = request('date') ?? today(); $sale_profit = Sale::where('business_id', $business_id)->whereDate('created_at', $date)->where('lossProfit', '>', 0)->sum('lossProfit'); $data = [ 'sales' => (float)Sale::where('business_id', $business_id)->whereDate('created_at', $date)->sum('totalAmount'), 'income' => (float)Income::where('business_id', $business_id)->whereDate('created_at', $date)->sum('amount') + $sale_profit, 'expense' => (float)Expense::where('business_id', $business_id)->whereDate('created_at', $date)->sum('amount'), 'purchase' => (float)Purchase::where('business_id', $business_id)->whereDate('created_at', $date)->sum('totalAmount'), ]; return response()->json([ 'message' => __('Data fetched successfully.'), 'data' => $data, ]); } public function dashboard() { $currentDate = Carbon::now(); $business_id = auth()->user()->business_id; $duration = request('duration'); // Set date range, format, and period based on selected duration switch ($duration) { case 'today': $start = $currentDate->copy()->startOfDay(); $end = $currentDate->copy()->endOfDay(); $format = 'H'; $period = $start->hoursUntil($end); break; case 'yesterday': $start = $currentDate->copy()->subDay()->startOfDay(); $end = $currentDate->copy()->subDay()->endOfDay(); $format = 'H'; $period = $start->hoursUntil($end); break; case 'last_seven_days': $start = $currentDate->copy()->subDays(6)->startOfDay(); $end = $currentDate->copy()->endOfDay(); $format = 'd'; $period = $start->daysUntil($end); break; case 'last_thirty_days': $start = $currentDate->copy()->subDays(29)->startOfDay(); $end = $currentDate->copy()->endOfDay(); $format = 'd'; $period = $start->daysUntil($end); break; case 'current_month': $start = $currentDate->copy()->startOfMonth(); $end = $currentDate->copy()->endOfMonth(); $format = 'd'; $period = $start->daysUntil($end); break; case 'last_month': $start = $currentDate->copy()->subMonthNoOverflow()->startOfMonth(); $end = $currentDate->copy()->subMonthNoOverflow()->endOfMonth(); $format = 'd'; $period = $start->daysUntil($end); break; case 'current_year': $start = $currentDate->copy()->startOfYear(); $end = $currentDate->copy()->endOfYear(); $format = 'M'; $period = $start->monthsUntil($end); break; case 'custom_date': if (request()->has('from_date') && request()->has('to_date')) { $start = Carbon::parse(request('from_date'))->startOfDay(); $end = Carbon::parse(request('to_date'))->endOfDay(); $format = 'd'; $period = $start->daysUntil($end); } else { return response()->json(['error' => 'From and To dates are required for custom date.'], 400); } break; default: return response()->json(['error' => 'Invalid duration'], 400); } // SQL date format for grouping $dateFormatSQL = match ($format) { 'H' => '%H', 'd' => '%Y-%m-%d', 'M' => '%Y-%m', default => '%Y-%m-%d', }; // Sales data fetch and map $sales_data = Sale::selectRaw("DATE_FORMAT(created_at, '$dateFormatSQL') as date, SUM(totalAmount) as amount") ->where('business_id', $business_id) ->whereBetween('created_at', [$start, $end]) ->groupBy('date') ->orderBy('date') ->get() ->map(function ($item) { $item->amount = (float) $item->amount; return $item; }) ->keyBy('date'); // Purchase data fetch and map $purchase_data = Purchase::selectRaw("DATE_FORMAT(created_at, '$dateFormatSQL') as date, SUM(totalAmount) as amount") ->where('business_id', $business_id) ->whereBetween('created_at', [$start, $end]) ->groupBy('date') ->orderBy('date') ->get() ->map(function ($item) { $item->amount = (float) $item->amount; return $item; }) ->keyBy('date'); $income_amount = Income::where('business_id', $business_id) ->whereBetween('created_at', [$start, $end]) ->sum('amount'); $sale_profit = Sale::where('business_id', $business_id) ->whereBetween('created_at', [$start, $end]) ->where('lossProfit', '>', 0) ->sum('lossProfit'); $expense_amount = Expense::where('business_id', $business_id) ->whereBetween('created_at', [$start, $end]) ->sum('amount'); $productQuery = Product::select('id', 'business_id', 'productName', 'product_type', 'created_at') ->with(['stocks:id,business_id,product_id,productStock,productPurchasePrice', 'combo_products.stock']) ->where('business_id', $business_id); $total_stock_value = 0; $products = $productQuery->get() ->map(function ($item) { $item->source = 'product'; return $item; }); foreach ($products as $product) { // SINGLE / VARIANT if (in_array($product->product_type, ['single', 'variant'])) { foreach ($product->stocks as $stock) { $total_stock_value += $stock->productStock * $stock->productPurchasePrice; } } // COMBO if ($product->product_type === 'combo') { foreach ($product->combo_products as $combo) { $childStock = $combo->stock; if ($childStock) { $total_stock_value += ($childStock->productStock / $combo->quantity) * $combo->purchase_price; } } } } $data = [ 'total_expense' => (float) $expense_amount, 'total_income' => (float) $income_amount + $sale_profit, 'total_items' => Product::where('business_id', $business_id)->count(), 'total_categories' => Category::where('business_id', $business_id)->count(), 'stock_value' => $total_stock_value, 'total_due' => (float) Sale::where('business_id', $business_id)->whereBetween('saleDate', [$start, $end])->sum('dueAmount'), 'total_profit' => (float) Sale::where('business_id', $business_id)->whereBetween('created_at', [$start, $end])->where('lossProfit', '>', 0)->sum('lossProfit'), 'total_loss' => (float) Sale::where('business_id', $business_id)->whereBetween('created_at', [$start, $end])->where('lossProfit', '<', 0)->sum('lossProfit'), 'sales' => $this->formatData($period, $sales_data, $format), 'purchases' => $this->formatData($period, $purchase_data, $format), ]; return response()->json([ 'message' => __('Data fetched successfully.'), 'data' => $data, ]); } private function formatData($period, $datas, $format) { $rows = []; foreach ($period as $date) { $key = $date->format($format); if ($format === 'M') { // Sum amounts for the month $dateKey = $date->format('Y-m'); $amount = $datas->filter(fn($value) => strpos($value->date, $dateKey) === 0)->sum('amount'); } elseif ($format === 'd') { // Get amount by full date $fullDateKey = $date->format('Y-m-d'); $amount = $datas->get($fullDateKey)?->amount ?? 0; } elseif ($format === 'H') { // Get amount by hour $amount = $datas->get($key)?->amount ?? 0; } else { // Default: treat as full date $fullDateKey = $date->format('Y-m-d'); $amount = $datas->get($fullDateKey)?->amount ?? 0; } $rows[] = [ 'date' => $key, 'amount' => $amount, ]; } return $rows; } }