year = (int) now()->year; } public function setYear(int $year): void { $this->year = $year; } public function updateAmount(int $categoryId, ?int $month, string $amount): void { $category = Category::findOrFail($categoryId); $household = auth()->user()->currentHousehold; if ($category->household_id !== $household->id) { abort(403); } $amount = is_numeric($amount) ? (float) $amount : 0.0; BudgetLine::updateOrCreate( [ 'household_id' => $household->id, 'category_id' => $categoryId, 'year' => $this->year, 'month' => $month, ], ['amount' => $amount], ); } /** * @return array keyed 'default',1..12 */ private function resolveRow(Category $category): array { $lines = $category->budgetLines()->where('year', $this->year)->get(); $default = (float) ($lines->firstWhere('month', null)->amount ?? 0); $row = ['default' => $default]; for ($m = 1; $m <= 12; $m++) { $override = $lines->firstWhere('month', $m); $row[$m] = $override ? (float) $override->amount : $default; } return $row; } public function render() { $household = auth()->user()->currentHousehold; $sections = collect(CategoryType::cases())->mapWithKeys(function (CategoryType $type) use ($household) { $categories = $household->categories() ->where('type', $type) ->orderBy('position') ->get() ->map(fn (Category $category) => [ 'category' => $category, 'row' => $this->resolveRow($category), ]); $totals = ['default' => 0.0]; for ($m = 1; $m <= 12; $m++) { $totals[$m] = 0.0; } foreach ($categories as $entry) { foreach ($entry['row'] as $key => $value) { $totals[$key] += $value; } } return [$type->value => ['categories' => $categories, 'totals' => $totals]]; }); $remaining = []; for ($m = 1; $m <= 12; $m++) { $remaining[$m] = $sections['revenu']['totals'][$m] - $sections['depense']['totals'][$m] - $sections['epargne']['totals'][$m]; } $sections['revenu'] = [...$sections['revenu'], 'remaining' => $remaining]; return view('livewire.plan.index', [ 'types' => CategoryType::cases(), 'sections' => $sections, 'months' => ['Janv', 'Févr', 'Mars', 'Avr', 'Mai', 'Juin', 'Juil', 'Août', 'Sept', 'Oct', 'Nov', 'Déc'], ]); } }