orderBy('created_at', 'desc') ->paginate(20); return view('budgets.index', compact('budgets')); } /** * Show the form for creating a new budget */ public function create() { return view('budgets.create'); } /** * Store a newly created budget */ public function store(Request $request) { $validated = $request->validate([ 'budget_name' => 'required|string|max:255', 'max_budget' => 'required|numeric|min:0', 'budget_type' => 'required|in:daily,weekly,monthly,custom,unlimited', 'custom_duration_days' => 'nullable|integer|min:1|required_if:budget_type,custom', ]); // Calculate budget_duration_sec based on type $duration = match($validated['budget_type']) { 'daily' => 86400, // 1 day 'weekly' => 604800, // 7 days 'monthly' => 2592000, // 30 days 'custom' => ($validated['custom_duration_days'] ?? 1) * 86400, 'unlimited' => null, }; $budget = Budget::create([ 'budget_id' => 'budget-' . Str::uuid(), 'max_budget' => $validated['max_budget'], 'budget_duration_sec' => $duration, ]); return redirect() ->route('budgets.index') ->with('success', 'Budget template created successfully!'); } /** * Display the specified budget */ public function show(string $id) { $budget = Budget::with('gatewayUsers')->findOrFail($id); // Get users without budget for potential assignment $availableUsers = GatewayUser::whereNull('budget_id') ->orWhere('budget_id', '') ->get(); return view('budgets.show', compact('budget', 'availableUsers')); } /** * Show the form for editing the specified budget */ public function edit(string $id) { $budget = Budget::findOrFail($id); // Determine budget type from duration $budgetType = 'unlimited'; if ($budget->budget_duration_sec) { $days = $budget->budget_duration_sec / 86400; $budgetType = match(true) { $days == 1 => 'daily', $days == 7 => 'weekly', $days == 30 => 'monthly', default => 'custom' }; } return view('budgets.edit', compact('budget', 'budgetType')); } /** * Update the specified budget */ public function update(Request $request, string $id) { $budget = Budget::findOrFail($id); $validated = $request->validate([ 'max_budget' => 'required|numeric|min:0', 'budget_type' => 'required|in:daily,weekly,monthly,custom,unlimited', 'custom_duration_days' => 'nullable|integer|min:1|required_if:budget_type,custom', ]); // Calculate budget_duration_sec based on type $duration = match($validated['budget_type']) { 'daily' => 86400, 'weekly' => 604800, 'monthly' => 2592000, 'custom' => ($validated['custom_duration_days'] ?? 1) * 86400, 'unlimited' => null, }; $budget->update([ 'max_budget' => $validated['max_budget'], 'budget_duration_sec' => $duration, ]); return redirect() ->route('budgets.show', $budget->budget_id) ->with('success', 'Budget updated successfully!'); } /** * Remove the specified budget */ public function destroy(string $id) { $budget = Budget::findOrFail($id); // Check if budget is assigned to users if ($budget->gatewayUsers()->count() > 0) { return redirect() ->route('budgets.index') ->with('error', 'Cannot delete budget that is assigned to users. Please reassign users first.'); } $budget->delete(); return redirect() ->route('budgets.index') ->with('success', 'Budget deleted successfully!'); } /** * Assign budget to users (bulk) */ public function assignUsers(Request $request, string $id) { $budget = Budget::findOrFail($id); $validated = $request->validate([ 'user_ids' => 'required|array', 'user_ids.*' => 'exists:users,user_id', ]); GatewayUser::whereIn('user_id', $validated['user_ids']) ->update([ 'budget_id' => $budget->budget_id, 'budget_started_at' => now(), 'next_budget_reset_at' => $budget->budget_duration_sec ? now()->addSeconds($budget->budget_duration_sec) : null, ]); return redirect() ->route('budgets.show', $budget->budget_id) ->with('success', count($validated['user_ids']) . ' user(s) assigned to budget successfully!'); } }